Skip to content
Snippets Groups Projects
Select Git revision
  • efbc330e2de3cc0eb652a65eda7f7a0ff84e81cf
  • master default protected
2 results

ui.js

  • Konrad Völkel's avatar
    Konrad Völkel authored
    efbc330e
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ui.js 5.78 KiB
    import { submitFeedback } from "./feedback.js";
    
    /** handle what needs to be displayed in chat container */
    export function appendMessage(content, className, linkId = null, akkordeonId = null, bestToken = null, query = null, answer = null) {
      const messageContainer = document.createElement('div');
      
      if (className === 'user-message') {
        const messageDiv = document.createElement('div');
        messageDiv.textContent = content;
        messageDiv.className = className;
        messageContainer.appendChild(messageDiv);
    
      } else {
    
        messageContainer.className = 'bot-message-container';
    
        const numberBox = document.createElement('div');
        numberBox.textContent = "⦿";
        numberBox.className = 'number-box';
        
        const messageDiv = document.createElement('div');
        messageDiv.textContent = content;
        messageDiv.className = className;
        
        const panelDiv = document.createElement('div');
        panelDiv.textContent = '➜';
        panelDiv.className = 'info-panel';
    
        panelDiv.setAttribute('data-question', encodeURIComponent(content));
        
        messageDiv.onclick = function () {
          copyToClipboard(content);
        };
        
        panelDiv.onclick = function (event) {
    
          event.stopPropagation();
    
          let nextElem = messageContainer.nextElementSibling;
          if (nextElem && nextElem.classList.contains('answer-container')) {
            nextElem.remove();
            panelDiv.classList.remove('active');
            return;
          }
          
          let highlightToken = answer.replace(bestToken, `<span class="highlight">${bestToken}</span>`);
          
          const answerContainer = document.createElement('div');
          answerContainer.className = 'answer-container';
          
          answerContainer.innerHTML = highlightToken;
          
          messageContainer.parentNode.insertBefore(answerContainer, messageContainer.nextSibling);
          panelDiv.classList.add('active');
        }
    
    
      messageContainer.appendChild(numberBox);
      messageContainer.appendChild(messageDiv);
      messageContainer.appendChild(panelDiv);
      
      }
    
      const messagesDiv = document.getElementById('messages');
      messagesDiv.appendChild(messageContainer);
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    }
    
    /** gets query from input field and performs search*/
    export function sendMessage(worker) {
    
    
      const userInput = document.getElementById('user-input');
      const message = userInput.value.trim();
      
      const resultsIframe = parent.document.getElementById('resultsIframe');
      const results = resultsIframe.contentDocument || resultsIframe.contentWindow.document;
      const resultsContainer = results.getElementById('results');
      
      /** hide results when message is sent */
      resultsContainer.innerHTML = '';
      setTimeout(() => {
          resultsIframe.style.display = 'none';
        }, 500);
        
      resultsIframe.style.display = 'block';
      resultsContainer.innerHTML = '';
    
    
      if (message !== "") {
    
        appendMessage(message, 'user-message');
    
        userInput.value = '';
        worker.postMessage({
          act: 'semanticSearch',
          query: message,
        });
      }
    }
    
    window.copyToClipboard = copyToClipboard;
    
    export function copyToClipboard(text) {
    
      window.navigator.clipboard.writeText(text)
        .then(() => {
          copySuccsess();
        })
    }
    
    /** show user that clipboard action was successful */
    let currentConfirm = null;
    let showTimeoutId = null;
    let hideTimeoutId = null;
    let removeTimeoutId = null;
    
    function copySuccsess() {
      
      if (currentConfirm) {
        clearTimeout(showTimeoutId);
        clearTimeout(hideTimeoutId);
        clearTimeout(removeTimeoutId);
        currentConfirm.remove();
      }
    
      currentConfirm = document.createElement('div');
      currentConfirm.innerText = 'Question copied to clipboard!';
      currentConfirm.classList.add('confirm');
      document.body.appendChild(currentConfirm);
    
      showTimeoutId = setTimeout(() => {
        currentConfirm.classList.add('visible');
      }, 10);
    
      hideTimeoutId = setTimeout(() => {
        currentConfirm.classList.remove('visible');
        removeTimeoutId = setTimeout(() => {
          currentConfirm.remove();
          currentConfirm = null;
        }, 500);
      }, 2000);
    }
    
    /** new feedback buttons with font-awesome style */
    export function drawFeedbackButtons(query, bestTokens) {
    
      const messagesDiv = document.getElementById('messages');
      const feedbackContainer = document.createElement('div');
      feedbackContainer.className = 'feedback-container';
    
      
      
      const plusButton = document.createElement('button');
      plusButton.innerHTML = '<i class="fa-solid fa-thumbs-up"></i>';
      plusButton.className = 'feedback-button thumbs-up';
      plusButton.onclick = function () {
        submitFeedback(query, bestTokens, 'up');
    
      };
    
      const minusButton = document.createElement('button');
      minusButton.innerHTML = '<i class="fa-solid fa-thumbs-down"></i>';
      minusButton.className = 'feedback-button thumbs-down';
      minusButton.onclick = function () {
    
        submitFeedback(query, bestTokens, 'down');
      };
    
      feedbackContainer.appendChild(plusButton);
      feedbackContainer.appendChild(minusButton);
      messagesDiv.appendChild(feedbackContainer);
    }
    
    /** Intro panel for chat resonses*/
    export function drawUserInfo() {
    
      const messagesDiv = document.getElementById('messages');
      const infoDiv = document.createElement('div');
    
      infoDiv.className = 'bot-intro';
      infoDiv.innerHTML = "This might be useful:<br>";
    
      messagesDiv.appendChild(infoDiv);
    }
    
    /** new message to inform user of the limited usability; out for now*/
    export function discloseLimitations() {
    
      const messagesDiv = document.getElementById('messages');
      const infoDiv = document.createElement('div');
    
      infoDiv.className = 'info-for-user';
      infoDiv.innerHTML = "Unfortunately, we're unable to provide direct links to the panel due to technical and policy restrictions.<br><ln><ln>Please copy the relevant question to your clipboard and use your browser's search function to locate the relevant panel on this page.";
      
      messagesDiv.appendChild(infoDiv);
    }