wiki-interface/ui/js/sidebar_en.js (369 lines of code) (raw):

/** * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ let isChatbotTyping = false; let typingIntervalId = null; let typingIndicatorMessage = 'Typing'; function loadMainContent(page) { const mainContentDiv = document.getElementById("main-content"); const loadingDiv = document.getElementById("loading"); const ratingDiv = document.getElementById("rating-content") let url = ""; switch (page) { case "about": url = "/ui/about"; break; case "userstory": url = "/ui/userstory"; break; case "testcase": url = "/ui/testcase"; break; case "testscript": url = "/ui/testscript"; break; case "testdata": url = "/ui/testdata"; break; case "codechatbot": url = "/ui/codechatbot"; break; case "docchatbot": url = "/ui/docchatbot"; break; case "codesearch": url = "/ui/codesearch"; break; case "solutionoverview": url = "/ui/solutionoverview"; break; case "solutiondatabase": url = "/ui/solutiondatabase"; break; case "solutionapi": url = "/ui/solutionapi"; break; case "solutiondep": url = "/ui/solutiondep"; break; case "solutionintegration": url = "/ui/solutionintegration"; break; case "solutionsecurity": url = "/ui/solutionsecurity"; break; case "selectproject": url = "/ui/selectproject"; break; default: url = "/ui/about"; break; } mainContentDiv.style.display = "none"; ratingDiv.style.display = "none"; loadingDiv.style.display = "block"; /* Fetch the HTML content from the specified URL */ fetch(url) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.text(); }) .then(htmlContent => { /* Update the innerHTML of the div with the loaded content */ mainContentDiv.innerHTML = htmlContent; }) .catch(error => { console.error("Error loading HTML:", error); mainContentDiv.innerHTML = "<p>Failed to load content. Please try again later.</p>"; }); waitContentLoad(() => { loadingDiv.style.display = "none"; mainContentDiv.style.display = "block"; /* If we're on chatbots, we'll wait for the sessions on GCS */ if (page == "codechatbot" || page == "docchatbot") { checkReady(); } else { if (page == "userstory" || page == "testcase" || page == "testscript") { fetchAndPopulateSelect(page); } else if (page == "selectproject") { loadProjectList(); } } }); } function loadProjectList() { fetch("/api/v1/projects") .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { const selectElement = document.getElementById("projectSelector"); // Clear existing options (optional) selectElement.innerHTML = ''; data.forEach(item => { const option = document.createElement('option'); option.value = item.projectId; option.text = item.projectName; selectElement.appendChild(option); }); }) .catch(error => { console.error('Error fetching data:', error); }); } function setProject() { // Get the selected project value from the dropdown const selectedProject = document.getElementById("projectSelector").value; // Construct the redirect URL const redirectUrl = `/ui/setproject/${selectedProject}`; window.location.href = redirectUrl; } function fetchAndPopulateSelect(type) { switch (type) { case "userstory": url = "/api/v1/userstoryoptions"; break; case "testcase": url = "/api/v1/testcaseoptions"; break; case "testscript": url = "/api/v1/testscriptoptions"; break; } fetch(url) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { const selectElement = document.getElementById("inputDocumentId"); // Clear existing options (optional) selectElement.innerHTML = ''; data.forEach(item => { const option = document.createElement('option'); option.value = item.value; // Assuming your JSON has a 'value' property option.text = item.label || item.value; // Use 'label' property if available, otherwise use 'value' selectElement.appendChild(option); }); }) .catch(error => { console.error('Error fetching data:', error); }); } function handleEnterKey(event) { if (event.key === 'Enter') { event.preventDefault(); sendMessage(); } } function displayUserMessage(message) { let chatBody = document.getElementById('chat-body'); const userMessage = document.createElement('div'); userMessage.className = 'user-message'; userMessage.innerText = message; chatBody.appendChild(userMessage); chatBody.scrollTop = chatBody.scrollHeight; } function displayChatbotMessage(message) { let chatBody = document.getElementById('chat-body'); if (isChatbotTyping) { // Remove the typing indicator when bot responds clearInterval(typingIntervalId); const typingIndicator = chatBody.querySelector('.typing-indicator'); if (typingIndicator) { chatBody.removeChild(typingIndicator); } isChatbotTyping = false; } const chatbotMessage = document.createElement('div'); chatbotMessage.className = 'chatbot-message'; let modifiedMessage = message.replace(/```mermaid\n(.*?)\n```/gs, (match, mermaidCode) => { const mermaidContainer = document.createElement('div'); mermaidContainer.classList.add('mermaid'); // Give it a class for mermaid.init() to find mermaidContainer.innerHTML = mermaidCode.trim(); // Trim any extra whitespace return mermaidContainer.outerHTML; // Replace the code block with the rendered HTML }); let renderedHTML = marked.parse(modifiedMessage); chatbotMessage.innerHTML = renderedHTML; chatBody.appendChild(chatbotMessage); chatBody.scrollTop = chatBody.scrollHeight; mermaid.init(); } function displayTypingIndicator() { let chatBody = document.getElementById('chat-body'); if (!isChatbotTyping) { // Create the typing indicator as a chatbot message const typingIndicator = document.createElement('div'); typingIndicator.className = 'chatbot-message typing-indicator'; typingIndicator.innerText = typingIndicatorMessage; chatBody.appendChild(typingIndicator); chatBody.scrollTop = chatBody.scrollHeight; isChatbotTyping = true; // Start the interval to cycle the typing indicator message typingIntervalId = setInterval(() => { if (typingIndicatorMessage === 'Typing...') { typingIndicatorMessage = 'Typing'; } else { typingIndicatorMessage += '.'; } typingIndicator.innerText = typingIndicatorMessage; }, 400); } } async function sendMessage() { let userInput = document.getElementById('user-input'); let chatbotType = document.getElementById('bot-type').value; let url = ""; switch (chatbotType) { case "code": url = "/api/v1/codemessage" break; case "doc": url = "/api/v1/docmessage" break } // Ignore empty messages const message = userInput.value.trim(); if (message === '') { return; } displayUserMessage(message); userInput.value = ''; try { // Display the typing indicator while waiting for the OpenAI's response displayTypingIndicator(); const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: message }), }); if (!response.ok) { console.log(response.status); throw new Error('Network response was not ok'); } const data = await response.json(); const chatbotResponse = data.message; displayChatbotMessage(chatbotResponse); } catch (error) { console.error('Error:', error); } } async function checkReady() { try { displayChatbotMessage("I'm preparing your chat session..."); // Display the typing indicator while waiting for the OpenAI's response displayTypingIndicator(); let chatbotType = document.getElementById('bot-type').value; let url = ""; switch (chatbotType) { case "code": url = "/api/v1/checkcodesession" break; case "doc": url = "/api/v1/checkdocsessione" break } while (true) { const response = await fetch(url, { method: 'GET', }); if (!response.ok) { break; } const data = await response.json(); console.log(data) if (data.status == "OK") { break; } await new Promise(resolve => setTimeout(resolve, 8000)); } displayChatbotMessage("Lets go?"); } catch (error) { console.error('Error:', error); } } function waitContentLoad(callback) { mermaid.initialize({ startOnLoad: true }); const targetDiv = document.getElementById("main-content"); const observer = new MutationObserver((mutations) => { if (targetDiv.innerHTML !== "") { // Check if div has content observer.disconnect(); // Stop observing callback(); // Execute your callback function } }); observer.observe(targetDiv, { childList: true, subtree: true }); // Observe for child list changes and subtree changes } /* Test Data Sample */ async function changeTestData() { /* Getting Selected Value */ var model = document.getElementById('inputModelId').value; var textarea = document.getElementById('inputDocumentId'); let url = ""; if (model == "csv") { url = "/static/csv_en.txt"; } else { url = "/static/json_en.txt"; } const response = await fetch(url, { method: 'GET', }); if (!response.ok) { console.log(response.status); throw new Error('Network response was not ok'); } const data = await response.text(); textarea.value = data; textarea.innerText = data; } function showPopup() { // Get the content from the div with id "ratingPageContent" const content = document.getElementById('ratingPageContent').value; // Check if the content exists if (!content) { console.error("Error: Element with id 'ratingPageContent' not found."); return; } // Create the popup window const popup = window.open('', '', 'width=800,height=600,menubar=no,toolbar=no,location=no,status=no,scrollbars=yes'); // Check if the popup was successfully opened. Some browsers might block popups. if (popup == null || typeof popup.document === 'undefined') { console.error("Error: Popup window could not be opened. Check your browser's popup blocker settings."); return; } // Write the content to the popup's document popup.document.write(`<!DOCTYPE html> <html> <head> <title>Popup</title> <style> body { font-family: sans-serif; } pre { white-space: pre-wrap; /* Allows line breaks */ } </style> </head> <body> <pre>${content}</pre> </body> </html>`); popup.document.close(); } async function performDownload() { // Get the content from the div with id "ratingPageContent" const content = document.getElementById('ratingPageContent').value; const b64source = btoa(content); const mimeType = document.getElementById('ratingMimeType').value; const transactionId = document.getElementById('ratingTransactionId').value; let data = { inputDoc: b64source, mimeType: mimeType, transactionId: transactionId } try { const response = await fetch('/api/v1/download', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (!response.ok) { throw new Error('Network response was not ok'); } const responseData = await response.text(); const popup = window.open('', '_blank', 'width=800,height=600'); if (popup) { popup.document.write(responseData); popup.document.close(); } else { alert("Could not open popup window. Please check your browser settings."); } } catch (error) { console.error('There was a problem with the fetch operation:', error); // Handle errors here (e.g., display an error message to the user) return null; // or some default value or error representation } }