diff mbox series

[v2,4/5] static: add rest.js to handle requests & respective messages

Message ID 20210722171251.2554142-5-raxel@google.com
State Superseded
Headers show
Series [v2,1/5] static: add JS Cookie Library to get csrftoken for fetch requests | expand
Related show

Commit Message

Raxel Gutierrez July 22, 2021, 5:12 p.m. UTC
Add js file to have REST API requests utilities JavaScript module to be
reused by other Patchwork js files making updates to objects.

 - Add function to make fetch requests that update properties through
   'PATCH' requests with the REST API endpoints.

 - Add functions that handle update & error messages for these 'PATCH'
   update requests following the Django messages framework format and
   form error styling.

The subsequent patch will make use of these functions which will be also
reused in future features the make use fetch requests to update object
fields.

Signed-off-by: Raxel Gutierrez <raxel@google.com>
---
 htdocs/README.rst |  7 +++++
 htdocs/js/rest.js | 71 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100644 htdocs/js/rest.js
diff mbox series

Patch

diff --git a/htdocs/README.rst b/htdocs/README.rst
index a018f31..12174de 100644
--- a/htdocs/README.rst
+++ b/htdocs/README.rst
@@ -138,6 +138,13 @@  js
 
   Part of Patchwork.
 
+``rest.js.``
+
+  Utility module for REST API requests to be used by other Patchwork js files
+  (fetch requests, handling update & error messages).
+
+  Part of Patchwork.
+
 ``selectize.min.js``
 
   Selectize is the hybrid of a ``textbox`` and ``<select>`` box. It's jQuery
diff --git a/htdocs/js/rest.js b/htdocs/js/rest.js
new file mode 100644
index 0000000..34d41f5
--- /dev/null
+++ b/htdocs/js/rest.js
@@ -0,0 +1,71 @@ 
+/**
+ * Sends fetch requests to update objects' properties using REST api endpoints.
+ * @param {string} url Path to the REST api endpoint.
+ * @param {{field: string, value: string}} data
+ *     field: Name of the property field to update.
+ *     value: Value to update the property field to.
+ * @param {{none: string, some: string}} updateMessage
+ *     none: Message when object update unsuccessful due to errors.
+ *     some: Message when object update successful.
+ */
+async function updateProperty(url, data, updateMessage) {
+    const request = new Request(url, {
+        method: 'PATCH',
+        mode: "same-origin",
+        headers: {
+            "X-CSRFToken": Cookies.get("csrftoken"),
+            "Content-Type": "application/json",
+        },
+        body: JSON.stringify(data),
+    });
+
+    await fetch(request)
+        .then(response => {
+            if (!response.ok) {
+                response.text().then(text => {
+                    // Error occurred, so update message specifies no objects updated
+                    handleUpdateMessages(updateMessage.none);
+                    handleErrorMessages(JSON.parse(text).detail);
+                });
+            } else {
+                // Update message for successful changes
+                handleUpdateMessages(updateMessage.some);
+            }
+        });
+}
+
+/**
+ * Populates update messages for fetch requests.
+ * @param {string} messageContent Text for update message.
+ */
+function handleUpdateMessages(messageContent) {
+    let messages = document.getElementById("messages");
+    if (messages == null) {
+        messages = document.createElement("div");
+        messages.setAttribute("id", "messages");
+    }
+    let message = document.createElement("div");
+    message.setAttribute("class", "message");
+    message.textContent = messageContent;
+    messages.appendChild(message);
+    if (messages) $(messages).insertAfter("nav");
+}
+
+/**
+ * Populates error messages for fetch requests.
+ * @param {string} errorMessage Text for error message.
+ */
+function handleErrorMessages(errorMessage) {
+    let container = document.getElementById("main-content");
+    let errorHeader = document.createElement("p");
+    let errorList = document.createElement("ul");
+    let error = document.createElement("li");
+    errorHeader.textContent = "The following error was encountered while updating comments:";
+    errorList.setAttribute("class", "errorlist");
+    error.textContent = errorMessage;
+    errorList.appendChild(error);
+    container.prepend(errorList);
+    container.prepend(errorHeader);
+}
+
+export { updateProperty, handleUpdateMessages, handleUpdateMessages};
\ No newline at end of file