mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-01-31 03:49:03 +00:00
Add result rendering for the user etc.
This commit is contained in:
parent
d2453c2cc3
commit
763183435d
@ -64,12 +64,9 @@ class Client {
|
||||
* This functions sends events to the View to trigger specific functions that
|
||||
* are handleing the representation of data stored in the model.
|
||||
*/
|
||||
notifyView(caseIdentifier, msg=null) {
|
||||
const event = new CustomEvent('notify', { detail: {
|
||||
'caseIdentifier': caseIdentifier,
|
||||
'msg': msg
|
||||
}
|
||||
});
|
||||
notifyView(caseIdentifier, detailObject={}) {
|
||||
detailObject.caseIdentifier = caseIdentifier;
|
||||
const event = new CustomEvent('notify', { detail: detailObject });
|
||||
console.info('Dispatching Notification:', caseIdentifier);
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
function saveMetaData() {
|
||||
let [payload, client, results, rest] = arguments;
|
||||
results.metaData.init(payload)
|
||||
client.recivedMetaData = true;
|
||||
console.info('Metada saved:', results);
|
||||
}
|
||||
|
||||
@ -18,21 +17,29 @@ function saveMetaData() {
|
||||
function prepareQueryData() {
|
||||
// deletes old data from query issued before this new query
|
||||
let [payload, client, results, rest] = arguments;
|
||||
// always initialize the results to delete data from the query issued before
|
||||
results.init();
|
||||
results.data.match_count = payload.match_count;
|
||||
client.requestQueryProgress = 0;
|
||||
client.notifyView('query-data-prepareing');
|
||||
client.notifyView('query-data-prepareing', { results: results });
|
||||
}
|
||||
|
||||
function saveQueryData(args) {
|
||||
let [payload, client, results, rest] = arguments;
|
||||
// get data matches length before new chun kdata is being inserted
|
||||
let dataLength = results.data.matches.length;
|
||||
// incorporating new chunk data into full results
|
||||
results.data.matches.push(...payload.chunk.matches);
|
||||
results.data.addData(payload.chunk.cpos_lookup, 'cpos_lookup');
|
||||
results.data.addData(payload.chunk.text_lookup, 'text_lookup');
|
||||
results.data.cpos_ranges = payload.chunk.cpos_ranges;
|
||||
results.data.match_count = results.data.matches.length;
|
||||
let queryFormElement = document.querySelector('#query-form');
|
||||
results.data.getQueryStr(queryFormElement);
|
||||
client.requestQueryProgress = payload.progress;
|
||||
client.notifyView('query-data-recieving')
|
||||
client.notifyView('query-data-recieving',
|
||||
{ results: results,
|
||||
client: client,
|
||||
dataLength: dataLength });
|
||||
console.info('Query data chunk saved', results.data);
|
||||
if (client.requestQueryProgress === 100) {
|
||||
client.notifyView('query-data-recieved');
|
||||
|
@ -28,7 +28,7 @@ function recieveConnected(type, client) {
|
||||
let errorText = `Error ${response.code} - ${response.msg}`;
|
||||
console.group('Connection failed!')
|
||||
console.error(`corpus_analysis_init: ${errorText}`);
|
||||
client.notifyView('conntecting-failed', errorText);
|
||||
client.notifyView('connecting-failed', { msg: errorText });
|
||||
console.groupEnd();
|
||||
}
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ class ResultsList extends List {
|
||||
* the options below are used.
|
||||
*/
|
||||
static options = {
|
||||
page: 10,
|
||||
page: 30,
|
||||
pagination: [{
|
||||
name: "paginationTop",
|
||||
paginationClass: "paginationTop",
|
||||
@ -37,7 +37,6 @@ class ResultsList extends List {
|
||||
};
|
||||
constructor(idOrElement, options) {
|
||||
super(idOrElement, options);
|
||||
this.options = options;
|
||||
/**
|
||||
* All span tokens which are holding events if expert
|
||||
* mode is on. Collected here to delete later on.
|
||||
@ -68,16 +67,22 @@ class ResultsList extends List {
|
||||
// TODO: multipleResults=false, atattchSomeCallback=false ?
|
||||
getHTMLElements(arrayOfSelectors) {
|
||||
for (let selector of arrayOfSelectors) {
|
||||
let element = document.querySelector(selector);
|
||||
let element;
|
||||
let elements;
|
||||
if (selector.startsWith('#')) {
|
||||
element = document.querySelector(selector);
|
||||
} else {
|
||||
elements = document.querySelectorAll(selector);
|
||||
}
|
||||
let cleanKey = [];
|
||||
selector = selector.replace('_', '-');
|
||||
selector = selector.replace(/_/g, '-');
|
||||
selector.match(/\w+/g).forEach((word) => {
|
||||
let tmp = word[0].toUpperCase() + word.slice(1);
|
||||
cleanKey.push(tmp);
|
||||
});
|
||||
cleanKey[0] = cleanKey[0].toLowerCase();
|
||||
cleanKey = cleanKey.join('');
|
||||
this[cleanKey] = element;
|
||||
this[cleanKey] = element ? element: elements;
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,54 +559,53 @@ class ResultsList extends List {
|
||||
|
||||
// Event function that changes the shown hits per page.
|
||||
// Just alters the resultsList.page property
|
||||
changeHitsPerPage(event) {
|
||||
changeHitsPerPage() {
|
||||
try {
|
||||
// console.log(this);
|
||||
this.page = event.target.value;
|
||||
this.update();
|
||||
this.activateInspect();
|
||||
this.pageChangeEventInteractionHandler(interactionElements);
|
||||
if (expertModeSwitchElement.checked) {
|
||||
this.expertModeOn("query-display"); // page holds new result rows, so add new tooltips
|
||||
}
|
||||
if (event.type === "change") {
|
||||
nopaque.flash("Updated matches per page.", "corpus")
|
||||
} catch (e) {
|
||||
// console.log(e);
|
||||
// console.log("resultsList has no results right now.");
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
} finally {
|
||||
this.page = this.displayOptionsFormResultsPerPage.value;
|
||||
this.update();
|
||||
}
|
||||
// TODO: reimplement the followinmg stuff
|
||||
// this.activateInspect();
|
||||
// this.pageChangeEventInteractionHandler(interactionElements);
|
||||
// if (expertModeSwitchElement.checked) {
|
||||
// this.expertModeOn("query-display"); // page holds new result rows, so add new tooltips
|
||||
// }
|
||||
}
|
||||
|
||||
// Event function triggered on context select change
|
||||
// also if pagination is clicked
|
||||
changeContext(event) {
|
||||
let array;
|
||||
let lc;
|
||||
let newContextValue;
|
||||
let rc;
|
||||
changeContext() {
|
||||
try {
|
||||
if (event.type === "change") {
|
||||
nopaque.flash("Updated context per match!", "corpus");
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
} finally {
|
||||
newContextValue = document.getElementById("display-options-form-result_context").value;
|
||||
lc = document.getElementsByClassName("left-context");
|
||||
rc = document.getElementsByClassName("right-context");
|
||||
let newContextValue = this.displayOptionsFormResultContext.value;
|
||||
let lc = document.querySelectorAll(".left-context");
|
||||
let rc = document.querySelectorAll(".right-context");
|
||||
for (let element of lc) {
|
||||
array = Array.from(element.childNodes);
|
||||
for (let element of array.reverse().slice(newContextValue)) {
|
||||
let arrayLc = Array.from(element.childNodes);
|
||||
for (let element of arrayLc.reverse().slice(newContextValue)) {
|
||||
element.classList.add("hide");
|
||||
}
|
||||
for (let element of array.slice(0, newContextValue)) {
|
||||
for (let element of arrayLc.slice(0, newContextValue)) {
|
||||
element.classList.remove("hide");
|
||||
}
|
||||
}
|
||||
for (let element of rc) {
|
||||
array = Array.from(element.childNodes);
|
||||
for (let element of array.slice(newContextValue)) {
|
||||
let arrayRc = Array.from(element.childNodes);
|
||||
for (let element of arrayRc.slice(newContextValue)) {
|
||||
element.classList.add("hide");
|
||||
}
|
||||
for (let element of array.slice(0, newContextValue)) {
|
||||
for (let element of arrayRc.slice(0, newContextValue)) {
|
||||
element.classList.remove("hide");
|
||||
}
|
||||
}
|
||||
|
@ -2,34 +2,112 @@
|
||||
* This file contains all the callbacks triggered by the notificationListener.
|
||||
*/
|
||||
|
||||
function connectingCallback(resultsList, msg=null) {
|
||||
function connectingCallback(resultsList, detail) {
|
||||
resultsList.getHTMLElements(['#analysis-init-modal']);
|
||||
resultsList.analysisInitModal = M.Modal.init(resultsList.analysisInitModal,
|
||||
{dismissible: false});
|
||||
resultsList.analysisInitModal.open();
|
||||
}
|
||||
|
||||
function connectedCallback(resultsList, msg=null) {
|
||||
function connectedCallback(resultsList, detail) {
|
||||
resultsList.analysisInitModal.close();
|
||||
}
|
||||
|
||||
function connectingFaildeCallback(resultsList, msg=null) {
|
||||
function connectingFaildeCallback(resultsList, detail) {
|
||||
resultsList.getHTMLElements([
|
||||
'#analysis-init-progress',
|
||||
'#analysis-init-error'
|
||||
]);
|
||||
resultsList.analysisInitProgress.classList.toggle('hide');
|
||||
resultsList.analysisInitError.classList.toggle('hide');
|
||||
resultsList.analysisInitError.textContent = msg;
|
||||
resultsList.analysisInitError.textContent = detail.msg;
|
||||
}
|
||||
|
||||
function queryDataPreparingCallback(resultsList, msg=null) {
|
||||
resultsList.getHTMLElements(['#interactions-menu']);
|
||||
function queryDataPreparingCallback(resultsList, detail) {
|
||||
// remove all items from resultsList, like from the query issued before
|
||||
resultsList.clear()
|
||||
// get needed HTML Elements
|
||||
let results = detail.results;
|
||||
resultsList.getHTMLElements(
|
||||
['#interactions-menu',
|
||||
'#recieved-match-count',
|
||||
'#total-match-count',
|
||||
'#text-lookup-count',
|
||||
'#text-lookup-titles',
|
||||
'#query-results-user-feedback',
|
||||
'#query-progress-bar',
|
||||
'#query-results-create',
|
||||
'#add-to-sub-results'
|
||||
]);
|
||||
// set some initial values for the user feedback
|
||||
resultsList.recievedMatchCount.textContent = 0;
|
||||
resultsList.totalMatchCount.textContent = results.data.match_count;
|
||||
resultsList.textLookupTitles.textContent = '';
|
||||
resultsList.textLookupCount.textContent = 0;
|
||||
// show or enable some things for the user
|
||||
resultsList.interactionsMenu.classList.toggle('hide', false)
|
||||
resultsList.addToSubResults.setAttribute("disabled", "");
|
||||
resultsList.queryResultsUserFeedback.classList.toggle('hide', false);
|
||||
resultsList.queryProgressBar.classList.toggle('hide', false);
|
||||
// hide ore disable some things for the user
|
||||
resultsList.queryResultsCreate.classList.toggle('disabled', true);
|
||||
}
|
||||
|
||||
function queryDataRecievingCallback(resultsList, detail) {
|
||||
// load the data into the resultsList and show them to the user
|
||||
let results = detail.results;
|
||||
let client = detail.client;
|
||||
let start = detail.dataLength;
|
||||
let resultItems = [];
|
||||
for (let [index, match] of Object.entries(results.data.matches).slice(start)) {
|
||||
resultItems.push({ ...match, ...{ 'index': parseInt(index) } });
|
||||
}
|
||||
if (client.dynamicMode) {
|
||||
resultsList.add(resultItems, (items) => {
|
||||
for (let item of items) {
|
||||
item.elm = resultsList.createResultRowElement(item, results.data);
|
||||
}
|
||||
});
|
||||
// update user feedback about query status
|
||||
resultsList.recievedMatchCount.textContent = results.data.matches.length;
|
||||
resultsList.queryProgressBar.firstElementChild.style.width = `${client.requestQueryProgress}%`;
|
||||
resultsList.textLookupCount.textContent = `${Object.keys(results.data.text_lookup).length}`;
|
||||
let titles = new Array();
|
||||
for (let [key, value] of Object.entries(results.data.text_lookup)) {
|
||||
titles.push(`${value.title} (${value.publishing_year})`);
|
||||
}
|
||||
resultsList.textLookupTitles.textContent = `${titles.join(', ')}`;
|
||||
// updating table on finished item creation callback via createResultRowElement
|
||||
resultsList.update();
|
||||
resultsList.changeHitsPerPage();
|
||||
resultsList.changeContext();
|
||||
} else if (!client.dynamicMode) {
|
||||
results.jsList.add(resultItems, (items) => {
|
||||
for (let item of items) {
|
||||
item.elm = results.jsList.createResultRowElement(item, payload.chunk,
|
||||
true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function queryDataRecievedCallback(resultsList, detail) {
|
||||
// hide or disable some things for the user
|
||||
resultsList.queryResultsUserFeedback.classList.toggle('hide');
|
||||
resultsList.queryProgressBar.classList.toggle('hide');
|
||||
// show or enable some things for the user
|
||||
resultsList.queryResultsCreate.classList.toggle('disabled');
|
||||
resultsList.addToSubResults.removeAttribute("disabled");
|
||||
|
||||
|
||||
}
|
||||
|
||||
// export the callbacks
|
||||
export { connectingCallback,
|
||||
export {
|
||||
connectingCallback,
|
||||
connectedCallback,
|
||||
connectingFaildeCallback,
|
||||
queryDataPreparingCallback, };
|
||||
queryDataPreparingCallback,
|
||||
queryDataRecievingCallback,
|
||||
queryDataRecievedCallback,
|
||||
};
|
@ -12,6 +12,8 @@ import {
|
||||
connectedCallback,
|
||||
connectingFaildeCallback,
|
||||
queryDataPreparingCallback,
|
||||
queryDataRecievingCallback,
|
||||
queryDataRecievedCallback,
|
||||
} from './callbacks.js';
|
||||
|
||||
function recieveNotification(eventType, resultsList) {
|
||||
@ -20,30 +22,32 @@ function recieveNotification(eventType, resultsList) {
|
||||
switch (caseIdentifier) {
|
||||
case 'connecting':
|
||||
console.info('Recieved notification:', caseIdentifier);
|
||||
connectingCallback(resultsList);
|
||||
connectingCallback(resultsList, event.detail);
|
||||
// execute callback
|
||||
break;
|
||||
case 'connected':
|
||||
console.info('Recieved notification:', caseIdentifier);
|
||||
connectedCallback(resultsList);
|
||||
connectedCallback(resultsList, event.detail);
|
||||
break;
|
||||
case 'connecting-failed':
|
||||
console.info('Recieved notification:', caseIdentifier);
|
||||
// execute callback
|
||||
connectingFaildeCallback(resultsList, event.detail.msg);
|
||||
connectingFaildeCallback(resultsList, event.detail);
|
||||
break;
|
||||
case 'query-data-prepareing':
|
||||
console.info('Recieved notification:', caseIdentifier);
|
||||
// execute callback
|
||||
queryDataPreparingCallback(resultsList);
|
||||
queryDataPreparingCallback(resultsList, event.detail);
|
||||
break;
|
||||
case 'query-data-recieving':
|
||||
console.info('Recieved notification:', caseIdentifier);
|
||||
// execute callback
|
||||
queryDataRecievingCallback(resultsList, event.detail);
|
||||
break;
|
||||
case 'query-data-recieved':
|
||||
console.info('Recieved notification:', caseIdentifier);
|
||||
// execute callback
|
||||
queryDataRecievedCallback(resultsList, event.detail);
|
||||
break;
|
||||
default:
|
||||
console.error('Recieved unkown notification case identifier');
|
||||
|
@ -2,18 +2,18 @@
|
||||
* Function to show a scroll to top button if the user has scrolled down
|
||||
* 250 pixels from the headline element.
|
||||
*/
|
||||
function scrollToTop() {
|
||||
let headline = document.querySelector(".headline");
|
||||
let scrollToTop = document.querySelector("#menu-scroll-to-top-div");
|
||||
window.addEventListener("scroll", (event) => {
|
||||
function scrollToTop(scrollToElementSelector, triggerElementSelector) {
|
||||
let headline = document.querySelector(scrollToElementSelector);
|
||||
let scrollToTop = document.querySelector(triggerElementSelector);
|
||||
window.addEventListener('scroll', (event) => {
|
||||
if (pageYOffset > 250) {
|
||||
scrollToTop.classList.toggle("hide", false);
|
||||
scrollToTop.classList.toggle('hide', false);
|
||||
} else {
|
||||
scrollToTop.classList.toggle("hide", true);
|
||||
scrollToTop.classList.toggle('hide', true);
|
||||
}
|
||||
});
|
||||
scrollToTop.onclick = () => {
|
||||
headline.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
|
||||
headline.scrollIntoView({behavior: 'smooth', block: 'end', inline: 'nearest'});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,9 @@ import {
|
||||
import {
|
||||
recieveNotification,
|
||||
} from '../../static/js/modules/corpus_analysis/view/listeners.js';
|
||||
import {
|
||||
scrollToTop,
|
||||
} from '../../static/js/modules/corpus_analysis/view/scrollToTop.js'
|
||||
|
||||
/**
|
||||
* Second Phase:
|
||||
@ -114,7 +117,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
* object as the View handeling the represnetation of the data.
|
||||
*/
|
||||
let results = new Results();
|
||||
let resultsView = new ResultsList('result-list', ResultsList.options);
|
||||
let resultsList = new ResultsList('result-list', ResultsList.options);
|
||||
/**
|
||||
* Register listeners listening to socket.io events and their callbacks
|
||||
* Afterwards load them.
|
||||
@ -145,18 +148,18 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
listenForMetaData]);
|
||||
client.loadSocketEventListeners();
|
||||
/**
|
||||
* Register resultsView listeners listening to nitification events.
|
||||
* Register resultsList listeners listening to nitification events.
|
||||
*/
|
||||
const listenForNotification = new NotificationListener('notify',
|
||||
recieveNotification);
|
||||
resultsView.setNotificationListeners([listenForNotification]);
|
||||
resultsView.loadNotificationListeners();
|
||||
resultsList.setNotificationListeners([listenForNotification]);
|
||||
resultsList.loadNotificationListeners();
|
||||
// Connect client to server
|
||||
client.notifyView('connecting');
|
||||
client.connect();
|
||||
|
||||
// Send a query and recieve its answer data
|
||||
let queryFormElement = document.getElementById('query-form');
|
||||
let queryFormElement = document.querySelector('#query-form');
|
||||
queryFormElement.addEventListener('submit', (event) => {
|
||||
try {
|
||||
/**
|
||||
@ -178,6 +181,25 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
results.data.getQueryStr(queryFormElement);
|
||||
client.query(results.data.query);
|
||||
});
|
||||
/**
|
||||
* Display events
|
||||
* 1. live update of hits per page if hits per page value is changed
|
||||
*/
|
||||
resultsList.getHTMLElements([
|
||||
'#display-options-form-results_per_page',
|
||||
'#display-options-form-result_context'
|
||||
]);
|
||||
resultsList.displayOptionsFormResultsPerPage.onchange = () => {
|
||||
resultsList.changeHitsPerPage();
|
||||
};
|
||||
resultsList.displayOptionsFormResultContext.onchange = () => {
|
||||
resultsList.changeContext();
|
||||
};
|
||||
|
||||
|
||||
|
||||
// enable scroll to Top
|
||||
scrollToTop('.headline', '#menu-scroll-to-top-div');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -7,7 +7,7 @@ results.-->
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="switch">
|
||||
Sub-Results creation:
|
||||
Sub-Results:
|
||||
<label>
|
||||
Off
|
||||
<input type="checkbox"
|
||||
|
@ -26,12 +26,14 @@ result.-->
|
||||
<span id="total-match-count"></span>
|
||||
matches loaded.
|
||||
<br>
|
||||
<br>
|
||||
Matches occured in
|
||||
<span id="text-lookup-count"></span>
|
||||
corpus files:
|
||||
<br>
|
||||
<span id=text-lookup-titles></span>
|
||||
</p>
|
||||
<br>
|
||||
<p class="hide" id="query-results-user-feedback">
|
||||
<i class="material-icons tiny">help</i>
|
||||
Server is sending your results.
|
||||
|
Loading…
x
Reference in New Issue
Block a user