Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
hainrich
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Konrad Völkel
hainrich
Commits
e25b66f4
Commit
e25b66f4
authored
3 months ago
by
Konrad Völkel
Browse files
Options
Downloads
Patches
Plain Diff
mostly minor visual changes
parent
a252bd53
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#152030
passed
3 months ago
Stage: deploy
Changes
5
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
index.js
+14
-30
14 additions, 30 deletions
index.js
modules/ui.js
+13
-35
13 additions, 35 deletions
modules/ui.js
modules/workerInterface.js
+1
-1
1 addition, 1 deletion
modules/workerInterface.js
semSearch.html
+20
-35
20 additions, 35 deletions
semSearch.html
styles.css
+46
-74
46 additions, 74 deletions
styles.css
with
94 additions
and
175 deletions
index.js
+
14
−
30
View file @
e25b66f4
...
...
@@ -10,7 +10,6 @@ const worker = new Worker('./worker.js', { type: 'module' });
/** get the up to date FAQ from site */
const
textData
=
await
extractFAQfromHTML
(
"
FAQ.html
"
);
/** import precompiled embeddings and check for missing entries */
console
.
time
(
"
loadLargeEmbeddings
"
);
let
embeddingStack
=
await
loadEmbedding
(
'
largeEmbedding
'
,
'
./embeddings/largeEmbedding.json
'
);
...
...
@@ -33,54 +32,41 @@ localStorage.setItem('largeEmbedding', JSON.stringify(embeddingStack));
localStorage
.
setItem
(
'
smallEmbedding
'
,
JSON
.
stringify
(
tokenEmbeddingStack
));
/** handeling results iframe */
const
inputElement
=
document
.
getElementById
(
'
user-input
'
);
const
results
Iframe
=
parent
.
document
.
getElementById
(
'
results
Iframe
'
);
const
results
Container
=
document
.
getElementById
(
'
results
'
);
let
topResult
=
null
;
inputElement
.
addEventListener
(
'
input
'
,
function
(
event
)
{
const
query
=
event
.
target
.
value
.
trim
();
const
results
=
resultsIframe
.
contentDocument
||
resultsIframe
.
contentWindow
.
document
;
const
resultsContainer
=
results
.
getElementById
(
'
results
'
);
/** hide results when no query is typed */
if
(
!
query
)
{
resultsContainer
.
innerHTML
=
''
;
setTimeout
(()
=>
{
resultsIframe
.
style
.
display
=
'
none
'
;
},
500
);
resultsContainer
.
style
.
display
=
'
none
'
;
return
;
}
results
Iframe
.
style
.
display
=
'
block
'
;
results
Container
.
style
.
display
=
'
block
'
;
resultsContainer
.
innerHTML
=
''
;
processQuery
(
query
,
worker
,
function
(
outputs
)
{
window
.
focus
();
outputs
.
forEach
(
async
output
=>
{
const
resultLink
=
results
.
createElement
(
'
a
'
);
resultLink
.
href
=
'
javascript:void(0);
'
;
/** display live results */
const
resultLink
=
document
.
createElement
(
'
div
'
)
;
resultLink
.
className
=
'
result
'
;
resultLink
.
style
.
display
=
'
block
'
;
/** display question text
in result iframe
*/
const
questionDiv
=
results
.
createElement
(
'
div
'
);
/** display question text */
const
questionDiv
=
document
.
createElement
(
'
div
'
);
questionDiv
.
className
=
'
result-question
'
;
questionDiv
.
innerHTML
=
`<strong>
${
output
.
question
}
</strong>`
;
resultLink
.
appendChild
(
questionDiv
);
/** display our most relevant token to question
in result iframe
*/
const
bestTokenDiv
=
results
.
createElement
(
'
div
'
);
/** display our most relevant token to question */
const
bestTokenDiv
=
document
.
createElement
(
'
div
'
);
bestTokenDiv
.
className
=
'
result-token
'
;
let
tokenText
=
output
.
bestToken
;
/** shorten our best token; only 100 chars displayed*/
if
(
tokenText
.
length
>
100
)
{
tokenText
=
tokenText
.
substring
(
0
,
100
);
}
...
...
@@ -100,9 +86,9 @@ inputElement.addEventListener('input', function (event) {
if
(
outputs
.
length
>
0
)
{
topResult
=
outputs
[
0
];
}
});
});
/** search for query on enter press and put it in chat */
document
.
getElementById
(
'
user-input
'
).
addEventListener
(
'
keypress
'
,
function
(
event
)
{
if
(
event
.
key
===
'
Enter
'
)
{
...
...
@@ -113,10 +99,8 @@ document.getElementById('user-input').addEventListener('keypress', function (eve
}
});
export
function
linkAndClick
(
output
)
{
saveMessage
();
setTimeout
(()
=>
{
const
encodedQuestion
=
encodeURIComponent
(
output
);
const
panels
=
document
.
querySelectorAll
(
...
...
This diff is collapsed.
Click to expand it.
modules/ui.js
+
13
−
35
View file @
e25b66f4
...
...
@@ -24,7 +24,6 @@ export function appendMessage(content, className, linkId = null, akkordeonId = n
const
panelDiv
=
document
.
createElement
(
'
div
'
);
panelDiv
.
innerHTML
=
'
<i class="fa-solid fa-down-long"></i>
'
;
panelDiv
.
className
=
'
info-panel
'
;
panelDiv
.
setAttribute
(
'
data-question
'
,
encodeURIComponent
(
content
));
messageDiv
.
onclick
=
function
(
event
)
{
...
...
@@ -33,15 +32,12 @@ export function appendMessage(content, className, linkId = null, akkordeonId = n
}
panelDiv
.
onclick
=
function
(
event
)
{
event
.
stopPropagation
();
let
nextElem
=
messageContainer
.
nextElementSibling
;
if
(
nextElem
&&
nextElem
.
classList
.
contains
(
'
answer-container
'
))
{
nextElem
.
remove
();
panelDiv
.
innerHTML
=
'
<i class="fa-solid fa-down-long"></i>
'
;
panelDiv
.
classList
.
remove
(
'
active
'
);
return
;
}
panelDiv
.
innerHTML
=
'
<i class="fa-solid fa-up-long"></i>
'
;
...
...
@@ -50,19 +46,15 @@ export function appendMessage(content, className, linkId = null, akkordeonId = n
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
'
);
...
...
@@ -72,29 +64,23 @@ export function appendMessage(content, className, linkId = null, akkordeonId = n
/** 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
'
);
const
resultsContainer
=
document
.
getElementById
(
'
results
'
);
/** hide results when message is sent */
resultsContainer
.
innerHTML
=
''
;
setTimeout
(()
=>
{
results
Iframe
.
style
.
display
=
'
none
'
;
results
Container
.
style
.
display
=
'
none
'
;
},
500
);
results
Iframe
.
style
.
display
=
'
block
'
;
results
Container
.
style
.
display
=
'
block
'
;
resultsContainer
.
innerHTML
=
''
;
if
(
message
!==
""
)
{
appendMessage
(
message
,
'
user-message
'
);
userInput
.
value
=
''
;
worker
.
postMessage
({
act
:
'
semanticSearch
'
,
...
...
@@ -103,29 +89,23 @@ export function sendMessage(worker) {
}
}
/** 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
,
'
good
'
);
};
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
,
'
bad
'
);
};
...
...
@@ -134,18 +114,16 @@ export function drawFeedbackButtons(query, bestTokens) {
messagesDiv
.
appendChild
(
feedbackContainer
);
}
/** Intro panel for chat resonses*/
/** Intro panel for chat res
p
onses
*/
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
()
{
...
...
This diff is collapsed.
Click to expand it.
modules/workerInterface.js
+
1
−
1
View file @
e25b66f4
...
...
@@ -52,7 +52,7 @@ export function handleWorker(events){
break
;
case
'
topResults
'
:
/** show results live in result
iframe
*/
/** show results live in result */
if
(
processQueryCache
)
{
const
outputs
=
results
.
slice
(
0
,
3
).
map
(
result
=>
({
question
:
result
.
question
,
...
...
This diff is collapsed.
Click to expand it.
semSearch.html
+
20
−
35
View file @
e25b66f4
...
...
@@ -2,7 +2,9 @@
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
HHU Search Helper
</title>
<title>
HHU Search Helper - Combined
</title>
<link
rel=
"stylesheet"
href=
"styles.css"
>
<link
rel=
"stylesheet"
href=
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
>
<style>
body
{
overflow
:
hidden
;
...
...
@@ -11,38 +13,21 @@
</head>
<body>
<iframe
id=
"chatIframe"
src=
"chatbox.html"
style=
"position: relative; width: 100%; border: none;"
title=
"HHU Search Helper"
></iframe>
<iframe
id=
"resultsIframe"
src=
"results.html"
style=
"position: sticky; left: 15px; min-height: 300px; transition: opacity 1s ease-in-out, transform 1s ease-in-out; background-color: #f0f0f0; width: 95%; overflow: hidden; padding: 10px; border-radius: 5px; border: none; display: none; overflow: hidden;"
></iframe>
<div
id=
"chatbox"
>
<div
id=
"chatbox-title"
>
Ask hAInrich
</div>
<div
id=
"messages"
></div>
<div
id=
"messageInfo"
></div>
<div
id=
"input-container"
>
<input
type=
"text"
id=
"user-input"
placeholder=
"Try asking: 'minimum admission grade' or 'I'm from outside the EU'"
>
<button
onclick=
"sendAsk()"
>
Ask
</button>
<script>
/** make iframes grow with iframes inside it */
function
adjustIframeSize
()
{
</div>
<div
id=
"results"
></div>
const
chatIframe
=
document
.
getElementById
(
'
chatIframe
'
);
const
resultsIframe
=
document
.
getElementById
(
'
resultsIframe
'
);
</div>
let
totalHeight
=
0
;
if
(
chatIframe
.
offsetHeight
)
{
totalHeight
+=
chatIframe
.
offsetHeight
;
}
if
(
resultsIframe
.
style
.
display
!==
'
none
'
&&
resultsIframe
.
offsetHeight
)
{
totalHeight
+=
resultsIframe
.
offsetHeight
;
}
if
(
window
.
frameElement
)
{
window
.
frameElement
.
style
.
height
=
totalHeight
+
'
px
'
;
}
}
document
.
getElementById
(
'
chatIframe
'
).
addEventListener
(
'
load
'
,
adjustIframeSize
);
document
.
getElementById
(
'
resultsIframe
'
).
addEventListener
(
'
load
'
,
adjustIframeSize
);
const
observer
=
new
MutationObserver
(
adjustIframeSize
);
observer
.
observe
(
document
.
body
,
{
childList
:
true
,
subtree
:
true
,
attributes
:
true
});
</script>
<script
type=
"module"
src=
"index.js"
async
></script>
</body>
</html>
This diff is collapsed.
Click to expand it.
styles.css
+
46
−
74
View file @
e25b66f4
...
...
@@ -2,20 +2,16 @@
font-family
:
Arial
,
sans-serif
;
}
#chatbox
{
background-color
:
#d3d3d3
;
position
:
sticky
;
width
:
100%
;
max-height
:
400px
;
overflow-x
:
hidden
;
max-height
:
900px
;
overflow
:
hidden
;
display
:
flex
;
flex-direction
:
column
;
overflow-y
:
hidden
;
}
#chatbox-title
{
position
:
relative
;
background-color
:
#003865
;
color
:
white
;
text-align
:
center
;
...
...
@@ -28,11 +24,12 @@
}
#messages
{
background-color
:
#d3d3d3
;
flex
:
1
;
left
:
10px
;
padding
:
10px
;
display
:
flex
;
max-height
:
27
0px
;
max-height
:
30
0px
;
flex-direction
:
column
;
overflow-x
:
hidden
;
z-index
:
-3
;
...
...
@@ -45,6 +42,7 @@
}
#input-container
{
background-color
:
#d3d3d3
;
display
:
flex
;
padding
:
10px
;
height
:
50px
;
...
...
@@ -72,7 +70,6 @@
background-color
:
#0056b3
;
}
.user-message
{
align-self
:
flex-end
;
background-color
:
#007bff
;
...
...
@@ -85,8 +82,6 @@
text-align
:
center
;
}
.answer-container
{
white-space
:
pre-wrap
;
align-self
:
flex-start
;
...
...
@@ -99,27 +94,13 @@
cursor
:
default
;
opacity
:
0
;
animation
:
showUp
0.3s
forwards
;
}
.highlight
{
background-color
:
rgb
(
59
,
136
,
172
);
color
:
white
;
/* Adjust as needed for contrast */
}
@keyframes
showUp
{
from
{
opacity
:
0
;
transform
:
translateY
(
-10px
);
}
to
{
opacity
:
1
;
transform
:
translateY
(
0
);
}
color
:
white
;
}
.info-for-user
{
position
:
relative
;
margin-right
:
auto
;
...
...
@@ -128,7 +109,6 @@
background-color
:
rgb
(
0
,
0
,
0
,
0.8
);
color
:
white
;
flex-direction
:
row
;
max-width
:
150px
;
text-align
:
left
;
display
:
inline-flex
;
align-items
:
center
;
...
...
@@ -140,7 +120,6 @@
max-width
:
50%
;
vertical-align
:
top
;
margin-right
:
20px
;
}
.bot-message
{
...
...
@@ -154,7 +133,6 @@
text-align
:
middle
;
z-index
:
100
;
cursor
:
pointer
;
}
.bot-intro
{
...
...
@@ -166,15 +144,11 @@
max-width
:
60%
;
word-wrap
:
break-word
;
text-align
:
middle
;
}
.bot-message-container
{
display
:
flex
;
align-items
:
stretch
;
}
.bot-message
:hover
{
...
...
@@ -185,7 +159,6 @@
transform
:
scale
(
1.03
);
}
.info-panel
{
background-color
:
#0056b3
;
color
:
rgb
(
255
,
255
,
255
);
...
...
@@ -249,7 +222,6 @@
.feedback-container
{
position
:
relative
;
margin-left
:
auto
;
left
:
-20px
;
color
:
#000
;
cursor
:
pointer
;
...
...
@@ -257,7 +229,6 @@
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
height
:
0px
;
padding
:
3px
;
font-size
:
12px
;
border-radius
:
4px
;
...
...
@@ -284,7 +255,6 @@
.feedback-container
:hover::after
{
opacity
:
1
;
visibility
:
visible
;
}
.feedback-button
{
...
...
@@ -307,59 +277,61 @@
}
#results
{
position
:
sticky
;
display
:
none
;
position
:
relative
;
background-color
:
#f0f0f0
;
width
:
auto
;
z-index
:
1000
;
margin
:
20px
;
padding
:
10px
;
width
:
95%
;
display
:
block
;
max-height
:
auto
;
min-height
:
200px
;
overflow
:
hidden
;
border-radius
:
5px
;
flex-grow
:
1
;
animation
:
showUp
0.3s
forwards
;
}
#results
.show
{
position
:
relative
;
display
:
block
;
opacity
:
1
;
transform
:
translateY
(
0
)
;
width
:
100%
;
visibility
:
visible
;
overflow
:
hidden
;
min-height
:
200px
;
padding
:
5px
;
}
#results
.result
{
p
adding
:
4px
8px
;
p
osition
:
relative
;
margin-bottom
:
4px
;
border-bottom
:
1px
solid
#ddd
;
font-size
:
17px
;
padding-left
:
5%
;
padding-right
:
10%
;
overflow
:
hidden
;
padding
:
5px
;
margin
:
10px
;
text-decoration
:
none
;
color
:
inherit
;
}
#results
.result
:hover
{
position
:
relative
;
cursor
:
pointer
;
background-color
:
#e0e0e0
;
overflow
:
hidden
;
padding
:
5px
;
font-size
:
18px
;
border-radius
:
5px
;
}
.confirm
{
position
:
fixed
;
top
:
60px
;
right
:
20px
;
background-color
:
#50bd54
;
color
:
#fff
;
padding
:
10px
15px
;
border-radius
:
5px
;
@keyframes
showUp
{
from
{
opacity
:
0
;
transition
:
opacity
0.5s
ease-in-out
;
pointer-events
:
none
;
z-index
:
5
;
transform
:
translateY
(
-10px
);
}
.confirm.visible
{
to
{
opacity
:
1
;
transform
:
translateY
(
0
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment