diff --git a/docs/yarn.lock b/docs/yarn.lock index e7b051a..921c9af 100755 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -2513,7 +2513,12 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.4.1: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -2535,17 +2540,7 @@ ajv@^6.12.2, ajv@^6.12.5, ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0: - version "8.11.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^8.8.2, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: version "8.13.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz" integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== @@ -7673,7 +7668,12 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -7683,6 +7683,11 @@ source-map@^0.7.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + space-separated-tokens@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" diff --git a/ui/agent-auth-token/index.html b/ui/agent-auth-token/index.html index 12ff607..5057e97 100755 --- a/ui/agent-auth-token/index.html +++ b/ui/agent-auth-token/index.html @@ -50,6 +50,10 @@ Search + + diff --git a/ui/alert-settings/index.html b/ui/alert-settings/index.html index 85475b8..fd2d365 100755 --- a/ui/alert-settings/index.html +++ b/ui/alert-settings/index.html @@ -50,6 +50,10 @@ Search + + diff --git a/ui/configuration-settings/index.html b/ui/configuration-settings/index.html index e9c1eed..12bb8fb 100755 --- a/ui/configuration-settings/index.html +++ b/ui/configuration-settings/index.html @@ -50,6 +50,10 @@ Search + + diff --git a/ui/event-triggers/index.html b/ui/event-triggers/index.html index c215815..71dc838 100755 --- a/ui/event-triggers/index.html +++ b/ui/event-triggers/index.html @@ -49,6 +49,10 @@ Search + + diff --git a/ui/index.html b/ui/index.html index f867771..e139138 100755 --- a/ui/index.html +++ b/ui/index.html @@ -52,6 +52,10 @@ Search + + diff --git a/ui/profile-settings/index.html b/ui/profile-settings/index.html index e100819..a776d0e 100755 --- a/ui/profile-settings/index.html +++ b/ui/profile-settings/index.html @@ -50,6 +50,10 @@ Search + + diff --git a/ui/prompt/index.html b/ui/prompt/index.html new file mode 100644 index 0000000..a3f4b87 --- /dev/null +++ b/ui/prompt/index.html @@ -0,0 +1,230 @@ + + + + + + + + + paradrop - Prompt + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+
+ + +
+
    + + + + +
    + + + + + Prompt +
    +
+
+ + + +
+ +
+ +
+
+ +
+ + + + +
+ + +
+ + +
+

Prompt

+
+ + +
+ + +
+ +
+
+
+
Paradrop-AI
+
+ + Hello! What are you searching for? +
+
+
+
+ +
+
+
+ + + +
+
+
+ +
+ Message copied to clipboard! +
+ +
+ +
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/ui/reports/index.html b/ui/reports/index.html index b9f9bc4..5a6d661 100755 --- a/ui/reports/index.html +++ b/ui/reports/index.html @@ -52,6 +52,10 @@ Search + + diff --git a/ui/static/css/custom_style.css b/ui/static/css/custom_style.css index b1ba5af..17aa1f1 100755 --- a/ui/static/css/custom_style.css +++ b/ui/static/css/custom_style.css @@ -1,88 +1,198 @@ /* ADDING FONTS /* open-sans-regular - latin */ @font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: url('../fonts/open-sans-v29-latin-regular.eot'); /* IE9 Compat Modes */ - src: local(''), - url('../fonts/open-sans-v29-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('../fonts/open-sans-v29-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ - url('../fonts/open-sans-v29-latin-regular.woff') format('woff'), /* Modern Browsers */ - url('../fonts/open-sans-v29-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ - url('../fonts/open-sans-v29-latin-regular.svg#OpenSans') format('svg'); /* Legacy iOS */ + font-family: "Open Sans"; + font-style: normal; + font-weight: 400; + src: url("../fonts/open-sans-v29-latin-regular.eot"); /* IE9 Compat Modes */ + src: local(""), + url("../fonts/open-sans-v29-latin-regular.eot?#iefix") + format("embedded-opentype"), + /* IE6-IE8 */ url("../fonts/open-sans-v29-latin-regular.woff2") + format("woff2"), + /* Super Modern Browsers */ url("../fonts/open-sans-v29-latin-regular.woff") + format("woff"), + /* Modern Browsers */ url("../fonts/open-sans-v29-latin-regular.ttf") + format("truetype"), + /* Safari, Android, iOS */ + url("../fonts/open-sans-v29-latin-regular.svg#OpenSans") format("svg"); /* Legacy iOS */ } /* SETTING UP FONT FOR ALL ELEMENTS */ * { - font-family: 'Open Sans', sans-serif; + font-family: "Open Sans", sans-serif; } /* SETTING UP THE LOOK OF THE TABLES */ .table { -border-spacing: 0; + border-spacing: 0; } .table tbody tr:nth-child(odd) { -background: #e4e4e4; + background: #e4e4e4; } .table td, .table th { -padding: 10px; + padding: 10px; } .table td:first-child, .table th:first-child { -border-top-left-radius: 4px; + border-top-left-radius: 4px; } .table td:last-child, .table th:last-child { -border-top-right-radius: 4px; + border-top-right-radius: 4px; } .table th { -background: #e55353; -color: #fff; -cursor: pointer; -font-weight: normal; -text-align: left; -text-transform: capitalize; -vertical-align: baseline; -white-space: nowrap; + background: #e55353; + color: #fff; + cursor: pointer; + font-weight: normal; + text-align: left; + text-transform: capitalize; + vertical-align: baseline; + white-space: nowrap; } .table th:hover { -color: #000; + color: #000; } .table th:hover::after { -color: inherit; -font-size: 1.2em; -content: ' \025B8'; + color: inherit; + font-size: 1.2em; + content: " \025B8"; } .table th::after { -font-size: 1.2em; -color: transparent; -content: ' \025B8'; + font-size: 1.2em; + color: transparent; + content: " \025B8"; } .table th.dir-d { -color: #000; + color: #000; } .table th.dir-d::after { -color: inherit; -content: ' \025BE'; + color: inherit; + content: " \025BE"; } .table th.dir-u { -color: #000; + color: #000; } .table th.dir-u::after { -color: inherit; -content: ' \025B4'; -} \ No newline at end of file + color: inherit; + content: " \025B4"; +} + +.chat-container { + flex-grow: 1; + overflow-y: auto; + padding: 1rem; +} + +.message-group { + display: flex; + flex-direction: column; + margin-bottom: 1rem; +} + +.message-label { + font-size: 0.8em; + margin-bottom: 0.2rem; + font-weight: bold; +} + +.user-group { + align-items: flex-end; +} + +.system-group { + align-items: flex-start; +} + +.chat-message { + max-width: 80%; + padding: 0.5rem 1rem; + border-radius: 1rem; + position: relative; +} + +.user-message { + background-color: #e55353; + color: white; +} + +.system-message { + background-color: #f1f3f5; + color: black; +} + +.input-container { + padding: 1rem; + background-color: #f8f9fa; + border-top: 1px solid #dee2e6; +} + +.chat-input { + resize: none; + height: 60px; +} + +.copy-button { + position: absolute; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + opacity: 0; + transition: opacity 0.3s ease; +} + +.user-message .copy-button { + left: -30px; + color: #e55353; +} + +.system-message .copy-button { + right: -30px; + color: #6c757d; +} + +.message-group:hover .copy-button { + opacity: 1; +} + +.char-count { + font-size: 0.8em; + color: #6c757d; +} + +.thinking { + display: inline-block; + width: 20px; + height: 20px; + border: 2px solid #e55353; + border-radius: 50%; + border-top-color: transparent; + animation: spin 1s linear infinite; + margin-right: 10px; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +pre code { + border-radius: 0.5rem; +} diff --git a/ui/static/js/config.js b/ui/static/js/config.js index 6b18792..932380e 100755 --- a/ui/static/js/config.js +++ b/ui/static/js/config.js @@ -1 +1,2 @@ export const URL = 'http://127.0.0.1:5000' +export const MODEL_URL = 'https://54.159.74.29:8000/v1/models/rag?q=' diff --git a/ui/static/js/prompt.js b/ui/static/js/prompt.js new file mode 100644 index 0000000..acfb549 --- /dev/null +++ b/ui/static/js/prompt.js @@ -0,0 +1,214 @@ +import { MODEL_URL } from './config.min.js' + +document.addEventListener("DOMContentLoaded", function () { + const chatContainer = document.getElementById("chatContainer"); + const chatInput = document.getElementById("chatInput"); + const sendButton = document.getElementById("sendMessage"); + const clearInputButton = document.getElementById("clearInput"); + const clearChatButton = document.getElementById("clearChat"); + const copyChatButton = document.getElementById("copyChat"); + const notificationBar = document.getElementById("notificationBar"); + + function showNotification(message) { + notificationBar.textContent = message; + notificationBar.style.display = "block"; + setTimeout(() => { + notificationBar.style.display = "none"; + }, 3000); + } + + function addMessage(content, isUser = true) { + const messageGroup = document.createElement("div"); + messageGroup.classList.add( + "message-group", + isUser ? "user-group" : "system-group" + ); + + const label = document.createElement("div"); + label.classList.add("message-label"); + label.textContent = isUser ? "You" : "Paradrop AI"; + + const messageElement = document.createElement("div"); + messageElement.classList.add( + "chat-message", + isUser ? "user-message" : "system-message" + ); + + const copyButton = document.createElement("button"); + copyButton.classList.add("copy-button"); + copyButton.textContent = "📋"; + copyButton.setAttribute("aria-label", "Copy message"); + copyButton.addEventListener("click", function () { + navigator.clipboard.writeText(content).then( + function () { + showNotification("Message copied to clipboard!"); + }, + function (err) { + console.error("Could not copy text: ", err); + } + ); + }); + + messageElement.appendChild(copyButton); + + const codeRegex = /```(\w+)?\s*([\s\S]*?)```/g; + let lastIndex = 0; + let match; + + while ((match = codeRegex.exec(content)) !== null) { + if (match.index > lastIndex) { + messageElement.appendChild( + document.createTextNode(content.slice(lastIndex, match.index)) + ); + } + + const pre = document.createElement("pre"); + const code = document.createElement("code"); + if (match[1]) { + code.className = `language-${match[1]}`; + } + code.textContent = match[2].trim(); + pre.appendChild(code); + messageElement.appendChild(pre); + + lastIndex = match.index + match[0].length; + } + + if (lastIndex < content.length) { + messageElement.appendChild( + document.createTextNode(content.slice(lastIndex)) + ); + } + + messageGroup.appendChild(label); + messageGroup.appendChild(messageElement); + + chatContainer.appendChild(messageGroup); + chatContainer.scrollTop = chatContainer.scrollHeight; + } + + function addThinkingMessage() { + const messageGroup = document.createElement("div"); + messageGroup.classList.add("message-group", "system-group"); + + const label = document.createElement("div"); + label.classList.add("message-label"); + label.textContent = "Paradrop AI"; + + const messageElement = document.createElement("div"); + messageElement.classList.add("chat-message", "system-message"); + + const thinkingIndicator = document.createElement("div"); + thinkingIndicator.classList.add("thinking"); + + const thinkingText = document.createTextNode("Thinking..."); + + messageElement.appendChild(thinkingIndicator); + messageElement.appendChild(thinkingText); + + messageGroup.appendChild(label); + messageGroup.appendChild(messageElement); + + chatContainer.appendChild(messageGroup); + chatContainer.scrollTop = chatContainer.scrollHeight; + + return messageGroup; + } + + clearInputButton.addEventListener("click", function () { + chatInput.value = ""; + }); + + clearChatButton.addEventListener("click", function () { + chatContainer.innerHTML = ""; + }); + + copyChatButton.addEventListener("click", function () { + const chatText = Array.from( + chatContainer.querySelectorAll(".message-group") + ) + .map((group) => { + const label = group.querySelector(".message-label").textContent; + const messageElement = group.querySelector(".chat-message"); + const message = Array.from(messageElement.childNodes) + .filter( + (node) => + node.nodeType === Node.TEXT_NODE || node.nodeName !== "BUTTON" + ) + .map((node) => node.textContent.trim()) + .join(""); + return `${label}: ${message}`; + }) + .join("\n\n"); + navigator.clipboard.writeText(chatText).then( + function () { + showNotification("Chat Copied to Clipboard!"); + }, + function (err) { + console.error("Could Not Copy Text: ", err); + } + ); + }); + + sendButton.addEventListener("click", function () { + const message = chatInput.value.trim(); + if (message) { + addMessage(message, true); + + chatInput.value = ""; + const thinkingMessage = addThinkingMessage(); + setTimeout(() => { + chatContainer.removeChild(thinkingMessage); + }, 18000); + + const apiUrl = + `${MODEL_URL}` + + encodeURIComponent(message); + + fetch(apiUrl, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP ERROR Status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + addMessage(data.answer, false); + }) + .catch((error) => { + console.error("Fetch Error:", error); + const thinkingMessage = addThinkingMessage(); + setTimeout(() => { + chatContainer.removeChild(thinkingMessage); + addMessage("Error Model Might Not Be Running", false); + }, 2000); + }); + } + }); + + chatInput.addEventListener("keypress", function (e) { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + sendButton.click(); + } + }); + + document.querySelectorAll(".copy-button").forEach((button) => { + button.addEventListener("click", function () { + const messageText = this.nextSibling.textContent.trim(); + navigator.clipboard.writeText(messageText).then( + function () { + showNotification("Message copied to clipboard!"); + }, + function (err) { + console.error("Could not copy text: ", err); + } + ); + }); + }); +}); diff --git a/ui/users-settings/index.html b/ui/users-settings/index.html index e4ab840..e626196 100755 --- a/ui/users-settings/index.html +++ b/ui/users-settings/index.html @@ -49,6 +49,10 @@ Search + +