Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[W.I.P.] Ubi integration #7144

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
6 changes: 4 additions & 2 deletions _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,13 @@ <h2>Related articles</h2>
anchors.add().remove('.subfooter h1, .subfooter h2');
</script>
{% endif %}
<script src="{{ '/assets/js/timeme.min.js' | relative_url }}"></script>
<script type="module" src="{{ '/assets/js/ubi.js' | relative_url }}"></script>
{% if site.search_enabled == false and site.use_custom_search == true %}
<script src="{{ '/assets/js/search.js' | relative_url }}"></script>
<script type="module" defer src="{{ '/assets/js/search.js' | relative_url }}"></script>
{% endif %}
<script src="{{ '/assets/js/copy-button.js' | relative_url }}"></script>
<script src="{{ '/assets/js/nav-scroll.js' | relative_url }}"></script>
<script src="{{ '/assets/js/listener.js' | relative_url }}"></script>
<script type="module" src="{{ '/assets/js/listener.js' | relative_url }}"></script>
</body>
</html>
14 changes: 12 additions & 2 deletions _layouts/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

{% include header.html %}


<div class="main-content-wrap-home">
<div id="main-content" class="main-content" role="main">
{{ content }}
Expand All @@ -30,7 +29,18 @@
</div>

{% include footer.html %}
<script src="{{ '/assets/js/search.js' | relative_url }}"></script>
<script src="{{ '/assets/js/timeme.min.js' | relative_url }}"></script>
<script type="text/javascript">
// Initialize library and start tracking time
TimeMe.initialize({
currentPageName: window.location.pathname,
idleTimeoutInSeconds: 5 // seconds
});
TimeMe.startTimer(window.location.pathname);
</script>

<script type="module" src="{{ '/assets/js/ubi.js' | relative_url }}"></script>
<script type="module" defer src="{{ '/assets/js/search.js' | relative_url }}"></script>
<script src="{{ '/assets/js/home-listener.js' | relative_url }}"></script>
</body>
</html>
20 changes: 19 additions & 1 deletion assets/js/listener.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as UBI from "./ubi.js";

const yesButton = document.getElementById('yes');
const noButton = document.getElementById('no');
const numCharsLabel = document.getElementById('num-chars');
Expand Down Expand Up @@ -48,7 +50,7 @@ function updateTextArea() {
}

// calculate the number of characters remaining
counter = 350 - commentTextArea.value.length;
const counter = 350 - commentTextArea.value.length;
numCharsLabel.innerText = counter + " characters left";
}

Expand All @@ -68,6 +70,22 @@ function sendFeedback() {

if (helpful === 'none' && comment === 'none') return;

try{
let e = new UBI.UbiEvent('user_feedback', {
message: `Relevance: ${helpful}, Comment: ${comment}`,
event_attributes:{
url:location.pathname,
helpful:helpful,
comment:comment
}
});
e.message_type = 'USER';
UBI.logEvent(e);

} catch(e){
console.warn(`UBI Error: ${e}`)
}

// split the comment into 100-char parts because of GA limitation on custom dimensions
const commentLines = ["", "", "", ""];
for (let i = 0; i <= (comment.length - 1)/100; i++) {
Expand Down
112 changes: 111 additions & 1 deletion assets/js/search.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import * as UBI from "./ubi.js";

(() => {

document.addEventListener('DOMContentLoaded', () => {
//
// Search field behaviors
Expand Down Expand Up @@ -66,6 +69,10 @@
highlightResult(e.target?.closest('.top-banner-search--field-with-results--field--wrapper--search-component--search-results--result'));
}, true);

elResults.addEventListener('click', e => {
clickResult(e.target?.closest('.top-banner-search--field-with-results--field--wrapper--search-component--search-results--result'));
}, true);

const debounceInput = () => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(doSearch, 300);
Expand Down Expand Up @@ -97,6 +104,7 @@
lastQuery = query;

abortPreviousCalls();
UBI.clearCache();

elSpinner?.classList.add(CLASSNAME_SPINNING);
if (!_showingResults) document.documentElement.classList.add('search-active');
Expand All @@ -118,10 +126,18 @@
if (!Array.isArray(data?.results) || data.results.length === 0) {
return showNoResults();
}
const [qid, result_ids] = UBI.cacheQueryResults(data.results);
let ubi_event = makeUbiEvent('search', 'search_results', {
id:UBI.hash(query),
query:query,
result_ids:result_ids
});
UBI.logEvent(ubi_event);

const chunks = data.results.map(result => result
? `
<div class="${searchResultClassName}">
<a href="${sanitizeAttribute(result.url)}">
<a id="${UBI.hash(result.url)}" href="${sanitizeAttribute(result.url)}">
<cite>${getBreadcrumbs(result)}</cite>
${sanitizeText(result.title || 'Unnamed Document')}
</a>
Expand Down Expand Up @@ -206,6 +222,11 @@
const searchResultClassName = 'top-banner-search--field-with-results--field--wrapper--search-component--search-results--result';
if (!node || !_showingResults || node.classList.contains(CLASSNAME_HIGHLIGHTED)) return;

const link = node.querySelector('a');
RasonJ marked this conversation as resolved.
Show resolved Hide resolved
if(link){
//xxyy logUbiEvent('item_hover', link);
}

elResults.querySelectorAll(`.${searchResultClassName}.highlighted`).forEach(el => {
el.classList.remove(CLASSNAME_HIGHLIGHTED);
});
Expand Down Expand Up @@ -247,14 +268,103 @@
}
};

const clickResult = node => {
const searchResultClassName = 'top-banner-search--field-with-results--field--wrapper--search-component--search-results--result';
if (!node || !_showingResults) return;

const link = node.querySelector('a');
if(link){
logUbiEvent('item_click', link);
}

return true;
};

const navToHighlightedResult = () => {
const searchResultClassName = 'top-banner-search--field-with-results--field--wrapper--search-component--search-results--result';
elResults.querySelector(`.${searchResultClassName}.highlighted a[href]`)?.click?.();
};

/**
* Find item and position clicked
* Modifies the ubi event data if the item is found
* @param {*} ubiEvent
RasonJ marked this conversation as resolved.
Show resolved Hide resolved
* @param {*} link
* @returns
*/
const setUbiClickData = (ubiEvent, link) => {
ubiEvent.event_attributes.position = new UBI.UbiPosition({x:link.offsetLeft, y:link.offsetTop});

if(link.hasAttribute('id')){
let id = link.id;
//try to find the item ordinal within the result list
let resultIds = sessionStorage.getItem('result_ids');
if(resultIds != null && resultIds.length > 0){
resultIds = resultIds.split(',');
let ordinal = resultIds.findIndex( i => i===id );
//if found, ordinal starts at 1
if(ordinal != -1){
ubiEvent.event_attributes.position.ordinal = ordinal + 1;
if(ubiEvent.message == undefined || ubi_event.message == null){
ubiEvent.message = `Clicked item ${ordinal+1} out of ${resultIds.length}`
}

try{
let searchResults = JSON.parse(sessionStorage.getItem('search_results'));
let obj = searchResults[id];
if(obj != null){
ubiEvent.event_attributes.object = obj;
ubiEvent.event_attributes.position.trail = getBreadcrumbs(obj);
}
}catch(e){
console.warn(e);
}
}
}
}
return ubiEvent;
};


const makeUbiEvent = (name, event_type, data) => {
let e = new UBI.UbiEvent(name);
RasonJ marked this conversation as resolved.
Show resolved Hide resolved
let t = TimeMe.getTimeOnPageInSeconds(window.location.pathname);
if(t != null){
e.event_attributes['dwell_seconds'] = t;
}

if(name == 'search'){
e.message_type = 'QUERY';
e.message = data.search_term;
e.event_attributes.object = data;
} else if(name == 'item_click') {
e = setUbiClickData(e, data);
} else {
switch(event_type) {
RasonJ marked this conversation as resolved.
Show resolved Hide resolved
case "event1":
break;
case "event2":
break;
default:{
if(e.event_attributes.object == null)
e.event_attributes.object = data;
}
}
}
return e;
}


const logUbiEvent = (name, data) => {
let event = makeUbiEvent(name, 'default', data)
UBI.logEvent(event);
};


const recordEvent = (name, data) => {
try {
gtag?.('event', name, data);
logUbiEvent(name, data);
} catch (e) {
// Do nothing
}
Expand Down
2 changes: 2 additions & 0 deletions assets/js/timeme.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading