Select Git revision
ui.js

Konrad Völkel authored
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);
}