{"version":3,"file":"add_news-1146ed73.js","sources":["../../js/posts-rest-api.js","../../js/posts-ui.js","../../js/posts.js","../../add_news.html?html-proxy&index=1.js"],"sourcesContent":["// модуль для работы с REST API сервера\n\n// адрес сервера\nconst serverUrl = \"http://localhost:8081\";\n\n// функция возвращает объект нужной структуры для отправки на сервер\nfunction createLineObject(id, text, title, date, image) {\n return {\n id,\n text,\n title,\n date,\n image,\n };\n}\n\n// обращение к серверу для получения всех записей (get)\nexport async function getAllLines() {\n const response = await fetch(`${serverUrl}/news`);\n if (!response.ok) {\n throw response.statusText;\n }\n return response.json();\n}\n\n// обращение к серверу для получения записи по первичному ключу (id) (get)\n// id передается в качестве части пути URL get-запроса\nexport async function getLine(id) {\n const response = await fetch(`${serverUrl}/news/${id}`);\n if (!response.ok) {\n throw response.statusText;\n }\n return response.json();\n}\n\n// обращение к серверу для создания записи (post)\n// объект отправляется в теле запроса (body)\nexport async function createLine(text, title, date, image) {\n const itemObject = createLineObject(0, text, title, date, image);\n\n const options = {\n method: \"POST\",\n body: JSON.stringify(itemObject),\n headers: {\n \"Accept\": \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n };\n\n const response = await fetch(`${serverUrl}/news`, options);\n if (!response.ok) {\n throw response.statusText;\n }\n return response.json();\n}\n\n// обращение к серверу для обновления записи по id (put)\n// объект отправляется в теле запроса (body)\n// id передается в качестве части пути URL get-запроса\nexport async function updateLine(id, text, title, date, image) {\n const newObject = createLineObject(id, text, title, date, image);\n\n const options = {\n method: \"PUT\",\n body: JSON.stringify(newObject),\n headers: {\n \"Accept\": \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n };\n\n const response = await fetch(`${serverUrl}/news/${id}`, options);\n if (!response.ok) {\n throw response.statusText;\n }\n return response.json();\n}\n\n// обращение к серверу для удаления записи по id (delete)\n// id передается в качестве части пути URL get-запроса\nexport async function deleteLine(id) {\n const options = {\n method: \"DELETE\",\n };\n\n const response = await fetch(`${serverUrl}/news/${id}`, options);\n if (!response.ok) {\n throw response.statusText;\n }\n return response.json();\n}\n","// модуль для работы с элементами управления\n\n// объект для удобного получения элементов\n// при обращении к атрибуту объекта вызывается\n// нужная функция для поиска элемента\nexport const cntrls = {\n form: document.getElementById(\"add-news-form\"),\n list: document.getElementById(\"list-news\"),\n title: document.getElementById(\"title\"),\n date: document.getElementById(\"date\"),\n text: document.getElementById(\"text\"),\n image: document.getElementById(\"image\"),\n imagePreview: document.getElementById(\"image-preview\"),\n};\n\n// Дефолтное превью\nexport const imagePlaceholder = \"https://via.placeholder.com/200\";\n\n// создать пост\nexport function createPost(elem) {\n cntrls.list.inserAdjacentHTML(getTemplate(elem));\n console.info(\"Post was creating\");\n}\n\n// шаблон поста\nfunction getTemplate(elem) {\n return `\n
\n
\n \"\"\n
\n
${elem.title}
\n

${elem.date}

\n

${elem.text}

\n
\n
\n
`;\n}\n","// модуль с логикой\nimport {\n getAllLines, getLine, createLine, updateLine, deleteLine,\n} from \"./posts-rest-api\";\nimport {\n cntrls, imagePlaceholder, createPost,\n} from \"./posts-ui\";\n\nasync function drawLines() {\n console.info(\"Try to load data\");\n if (!cntrls.list) {\n return;\n }\n const data = await getAllLines();\n cntrls.list.innerHTML = '';\n // data.array.forEach((element) => {\n // createPost(element);\n // });\n\n data.forEach((item) => {\n cntrls.table.appendChild(\n createPost(\n item\n // функции передаются в качестве параметра\n // это очень удобно, так как аргументы функций доступны только\n // в данном месте кода и не передаются в сервисные модули\n //() => location.assign(`page-edit.html?id=${item.id}`),\n //() => removeLine(item.id),\n ),\n );\n });\n}\n\nasync function addLine(text, title, date, image) {\n console.info(\"Try to add item\");\n // вызов метода REST API для добавления записи\n const data = await createLine(text, title, date, image);\n console.info(\"Added\");\n console.info(data);\n // загрузка и заполнение table\n drawLines();\n}\n\nasync function editLine(id, title, date, text) {\n console.info(\"Try to update item\");\n // вызов метода REST API для обновления записи\n const data = await updateLine(id, title, date, text);\n console.info(\"Updated\");\n console.info(data);\n // загрузка и заполнение table\n drawLines();\n}\n\nasync function removeLine(id) {\n if (!confirm(\"Do you really want to remove this item?\")) {\n console.info(\"Canceled\");\n return;\n }\n console.info(\"Try to remove item\");\n // вызов метода REST API для удаления записи\n const data = await deleteLine(id);\n console.info(data);\n // загрузка и заполнение table\n drawLines();\n}\n\n// функция для получения содержимого файла в виде base64 строки\n// https://ru.wikipedia.org/wiki/Base64\nasync function readFile(file) {\n const reader = new FileReader();\n\n // создание Promise-объекта для использования функции\n // с помощью await (асинхронно) без коллбэков (callback)\n // https://learn.javascript.ru/promise\n return new Promise((resolve, reject) => {\n // 2. \"Возвращаем\" содержимое когда файл прочитан\n // через вызов resolve\n // Если не использовать Promise, то всю работу по взаимодействию\n // с REST API пришлось бы делать в обработчике (callback) функции\n // onloadend\n reader.onloadend = () => {\n const fileContent = reader.result;\n // Здесь могла бы быть работа с REST API\n // Чтение заканчивает выполняться здесь\n resolve(fileContent);\n };\n // 3. Возвращаем ошибку\n reader.onerror = () => {\n // Или здесь в случае ошибки\n reject(new Error(\"oops, something went wrong with the file reader.\"));\n };\n // Шаг 1. Сначала читаем файл\n // Чтение начинает выполняться здесь\n reader.readAsDataURL(file);\n });\n}\n\n// функция для обновления блока с превью выбранного изображения\nasync function updateImagePreview() {\n // получение выбранного файла\n // возможен выбор нескольких файлов, поэтому необходимо получить только первый\n const file = cntrls.image.files[0];\n // чтение содержимого файла в виде base64 строки\n const fileContent = await readFile(file);\n console.info(\"base64 \", fileContent);\n // обновление атрибута src для тега img с id image-preview\n cntrls.imagePreview.src = fileContent;\n}\n\n// Функция для обработки создания и редактирования элементов таблицы через страницу page-edit.html\n// eslint-disable-next-line import/prefer-default-export\nexport async function linesPageForm() {\n console.info(\"linesPageForm\");\n // func1 = (id) => {} аналогично function func1(id) {}\n const goBack = () => location.assign(\"/news.html\");\n\n // Вызов функции обновления превью изображения при возникновении\n // события onchange в тэге input с id image\n cntrls.image.addEventListener(\"change\", () => updateImagePreview());\n\n // получение параметров GET-запроса из URL\n // параметры перечислены после символа ? (?id=1&color=black&...)\n const urlParams = new URLSearchParams(location.search);\n\n // получение значения конкретного параметра (id)\n // указан только при редактировании\n const currentId = urlParams.get(\"id\");\n // если id задан\n if (currentId) {\n try {\n // вызов метода REST API для получения записи по первичному ключу(id)\n const line = await getLine(currentId);\n // заполнение формы для редактирования\n cntrls.title.value = line.title;\n cntrls.date.value = line.date;\n cntrls.text.value = line.text;\n // заполнение превью\n // Если пользователь выбрал изображение, то оно загружается\n // в тэг image с id image - preview\n // иначе устанавливается заглушка, адрес которой указан в imagePlaceholder\n cntrls.imagePreview.src = line.image ? line.image : imagePlaceholder;\n } catch {\n // в случае ошибки происходит возврат к page4\n goBack();\n }\n }\n\n // обработчик события отправки формы\n // возникает при нажатии на кнопку (button) с типом submit\n // кнопка должна находится внутри тега form\n cntrls.form.addEventListener(\"submit\", async (event) => {\n console.info(\"Form onSubmit\");\n // отключение стандартного поведения формы при отправке\n // при отправке страница обновляется и JS перестает работать\n event.preventDefault();\n event.stopPropagation();\n // если форма не прошла валидацию, то ничего делать не нужно\n if (!cntrls.form.checkValidity()) {\n return;\n }\n\n let imageBase64 = \"\";\n // Получение выбранного пользователем изображения в виде base64 строки\n // Если пользователь ничего не выбрал, то не нужно сохранять в БД\n // дефолтное изображение\n if (cntrls.imagePreview.src !== imagePlaceholder) {\n // Загрузка содержимого атрибута src тэга img с id image-preview\n // Здесь выполняется HTTP запрос с типом GET\n const result = await fetch(cntrls.imagePreview.src);\n // Получение из HTTP-ответа бинарного содержимого\n const blob = await result.blob();\n // Получение base64 строки для файла\n // Здесь выполняется Promise из функции readFile\n // Promise позволяет писать линейный код для работы с асинхронными методами\n // без использования обработчиков (callback) с помощью await\n imageBase64 = await readFile(blob);\n }\n\n // если значение параметра запроса не задано,\n // то необходимо выполнить добавление записи\n // иначе обновление записи\n if (!currentId) {\n await addLine(\n cntrls.text.value,\n cntrls.title.value,\n cntrls.date.value,\n imageBase64,\n );\n } else {\n await editLine(\n currentId,\n cntrls.text.value,\n cntrls.title.value,\n cntrls.date.value,\n imageBase64,\n );\n }\n // возврат к странице page4\n goBack();\n });\n}\n","\n import validation from \"./js/validation.js\";\n import { linesPageForm } from \"./js/posts.js\"\n\n document.addEventListener('DOMContentLoaded', () => {\n validation();\n linesPageForm();\n });\n "],"names":["serverUrl","createLineObject","id","text","title","date","image","getAllLines","response","getLine","createLine","itemObject","options","updateLine","newObject","cntrls","imagePlaceholder","createPost","elem","getTemplate","drawLines","data","item","addLine","editLine","readFile","file","reader","resolve","reject","fileContent","updateImagePreview","linesPageForm","goBack","currentId","line","event","imageBase64","blob","validation"],"mappings":"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"}