From 8886dadeaca44e6cb061844ba6502c109c2667f1 Mon Sep 17 00:00:00 2001 From: Fergus McDowall Date: Fri, 20 Sep 2024 16:06:47 +0200 Subject: [PATCH] various ways to upload documents from the browser --- www_root/utils/uploader/index.html | 152 +++++++++++++--------------- www_root/utils/uploader/styles.css | 39 +++++++ www_root/utils/uploader/uploader.js | 97 ++++++++++++++++++ 3 files changed, 205 insertions(+), 83 deletions(-) create mode 100644 www_root/utils/uploader/styles.css create mode 100644 www_root/utils/uploader/uploader.js diff --git a/www_root/utils/uploader/index.html b/www_root/utils/uploader/index.html index 86e89e2..a2093dd 100644 --- a/www_root/utils/uploader/index.html +++ b/www_root/utils/uploader/index.html @@ -1,34 +1,8 @@ Uploader - + + @@ -36,12 +10,10 @@ loading... -
- -

- +

+ Click here to upload by manually inputting documents +

-
- -

- - - +

+ Send data in curl command itself: + +

+curl -X 'POST' \
+  'http://localhost:3030/API/PUT?caseSensitive=true&nGrams=%7B%0A%20%20%22lengths%22%3A%20%5B%0A%20%20%20%201%0A%20%20%5D%2C%0A%20%20%22join%22%3A%20%22%20%22%2C%0A%20%20%22fields%22%3A%20%5B%5D%0A%7D&replace=%7B%0A%20%20%22fields%22%3A%20%5B%5D%2C%0A%20%20%22values%22%3A%20%7B%7D%0A%7D&tokenSplitRegex=%2F%5B%5Cp%7BL%7D%5Cd%5D%2B%2Fgu' \
+  -H 'accept: */*' \
+  -H 'Content-Type: application/json' \
+  -d '[
+  {
+    "_id": "string"
+  }
+]'
+        
+

+ +

+ + Send file data from curl command: + +

+curl -X 'POST' \
+  'http://localhost:3030/API/PUT?caseSensitive=true&nGrams=%7B%0A%20%20%22lengths%22%3A%20%5B%0A%20%20%20%201%0A%20%20%5D%2C%0A%20%20%22join%22%3A%20%22%20%22%2C%0A%20%20%22fields%22%3A%20%5B%5D%0A%7D&replace=%7B%0A%20%20%22fields%22%3A%20%5B%5D%2C%0A%20%20%22values%22%3A%20%7B%7D%0A%7D&tokenSplitRegex=%2F%5B%5Cp%7BL%7D%5Cd%5D%2B%2Fgu' \
+  -H 'accept: */*' \
+  -H 'Content-Type: application/json' \
+  --data '@myFile.json'
+        
+

+ + +
+ + + +
+
+  
 
diff --git a/www_root/utils/uploader/styles.css b/www_root/utils/uploader/styles.css
new file mode 100644
index 0000000..99aa5cc
--- /dev/null
+++ b/www_root/utils/uploader/styles.css
@@ -0,0 +1,39 @@
+textarea:invalid {
+  border: 3px solid red;
+  background: pink;
+}
+
+textarea:valid {
+  border: 2px solid lime;
+}
+
+#loading {
+  align-items: center;      /* Vertically centers the image */
+  background-color: rgba(0, 0, 0, 0.3);
+  display: none;
+  height: 100%;            /* Full viewport height */
+  justify-content: center;  /* Horizontally centers the image */
+  left: 0;
+  position: fixed;
+  top: 0;
+  width: 100%;             /* Full viewport width */
+  z-index: 9999;
+}
+
+#loading-img {
+  max-width: 400px;  /* Optional: Ensures the image is responsive */
+}
+
+#server-response-details {
+  display: none;
+}
+
+label {
+  display: block;
+}
+
+summary {
+  cursor: pointer;
+}
+
+summary:hover { text-decoration: underline; }
diff --git a/www_root/utils/uploader/uploader.js b/www_root/utils/uploader/uploader.js
new file mode 100644
index 0000000..d4ccb65
--- /dev/null
+++ b/www_root/utils/uploader/uploader.js
@@ -0,0 +1,97 @@
+// make it easier to grab elements
+const el = id => document.getElementById(id)
+
+// grab value of documents from textarea
+const textareaInput = () =>
+  JSON.stringify(JSON.parse(el('json').value), null, 2)
+
+// resize textarea to its contents
+const resizeTextarea = () =>
+  el('json').setAttribute('rows', el('json').value.split(/\r|\r\n|\n/).length)
+
+// log server responses to web page
+const printResponse = response => {
+  el('server-response').innerHTML =
+    '\n\n' +
+    new Date().toISOString() +
+    ' ->\n\n' +
+    JSON.stringify(response, null, 2) +
+    el('server-response').innerHTML
+}
+
+const loading = toggle =>
+  toggle
+    ? (el('loading').style.display = 'flex')
+    : (el('loading').style.display = 'none')
+
+// upload to server from textarea
+const PUTFromTextArea = () => {
+  loading(true)
+  PUT(textareaInput())
+}
+
+// upload to server from file
+PUTFromFile = () => {
+  loading(true)
+  const reader = new FileReader()
+  const [file] = el('file-upload').files
+  if (file) reader.readAsText(file)
+  reader.addEventListener('load', () => PUT(reader.result))
+}
+
+// upload to server
+const PUT = json =>
+  fetch(
+    new Request('/API/PUT', {
+      body: json,
+      headers: {
+        'Access-Control-Allow-Origin': '*'
+      },
+      method: 'POST'
+    })
+  )
+    .then(res => res.json())
+    .then(reponse => {
+      console.log(reponse)
+      loading(false)
+      printResponse(reponse)
+      resizeTextarea()
+    })
+    .catch(console.error)
+
+// pretty input validation
+const validateInput = () => {
+  // set invalid, not submittable as default
+  el('put').disabled = true
+  el('json').setCustomValidity('')
+  validation: try {
+    if (el('json').value == '') break validation // valid, but not submittable
+    el('json').value = textareaInput()
+    el('put').disabled = false // if no error thrown, json is valid
+  } catch (e) {
+    el('json').setCustomValidity(e.toString()) // JSON is invalid
+  } finally {
+    resizeTextarea()
+  }
+}
+
+// only open one 
element at a time +const setDetails = () => { + const details = document.querySelectorAll('details') + details.forEach(targetDetail => { + targetDetail.addEventListener('click', () => { + // Close all details that are not targetDetail + details.forEach(detail => { + if (detail !== targetDetail) { + detail.removeAttribute('open') + } + }) + }) + }) +} + +// if browser initialises wit content in textarea- validate! +window.onload = () => { + validateInput() + setDetails() +}