Skip to content
Snippets Groups Projects
Commit 64f8f82f authored by Stephan Porada's avatar Stephan Porada :speech_balloon:
Browse files

Add logic for data export etc.

parent 76318343
No related branches found
No related tags found
No related merge requests found
Showing
with 286 additions and 211 deletions
...@@ -16,7 +16,7 @@ class Client { ...@@ -16,7 +16,7 @@ class Client {
this.logging = logging; this.logging = logging;
this.requestQueryProgress = 0; this.requestQueryProgress = 0;
this.socket = socket; this.socket = socket;
this.socketEventListeners = {}; this.eventListeners = {};
this.connected = false; this.connected = false;
...@@ -44,9 +44,9 @@ class Client { ...@@ -44,9 +44,9 @@ class Client {
} }
// Registers one or more SocketEventListeners to the Client. // Registers one or more SocketEventListeners to the Client.
setSocketEventListeners(socketEventListeners) { setSocketEventListeners(eventListeners) {
for (let socketEventListener of socketEventListeners) { for (let eventListener of eventListeners) {
this.socketEventListeners[socketEventListener.type] = socketEventListener; this.eventListeners[eventListener.type] = eventListener;
} }
} }
...@@ -55,7 +55,7 @@ class Client { ...@@ -55,7 +55,7 @@ class Client {
* type strings because they double as the socket event event names. * type strings because they double as the socket event event names.
*/ */
loadSocketEventListeners() { loadSocketEventListeners() {
for (let [type, listener] of Object.entries(this.socketEventListeners)) { for (let [type, listener] of Object.entries(this.eventListeners)) {
listener.listenerFunction(type, this); listener.listenerFunction(type, this);
} }
} }
...@@ -66,8 +66,8 @@ class Client { ...@@ -66,8 +66,8 @@ class Client {
*/ */
notifyView(caseIdentifier, detailObject={}) { notifyView(caseIdentifier, detailObject={}) {
detailObject.caseIdentifier = caseIdentifier; detailObject.caseIdentifier = caseIdentifier;
const event = new CustomEvent('notify', { detail: detailObject }); const event = new CustomEvent('notify-view', { detail: detailObject });
console.info('Dispatching Notification:', caseIdentifier); console.info('Client dispatching Notification:', caseIdentifier);
document.dispatchEvent(event); document.dispatchEvent(event);
} }
...@@ -105,16 +105,38 @@ class Client { ...@@ -105,16 +105,38 @@ class Client {
'socket.emit for the query', queryStr); 'socket.emit for the query', queryStr);
this.socket.emit('corpus_analysis_query', queryStr); this.socket.emit('corpus_analysis_query', queryStr);
} }
// create results data either from all results or from all marked sub results
getResultsData(resultsType, dataIndexes, results) {
// TODO: where to put all the stuff that deactivates all the buttons because cqp server cannot handle mutliple requests?
// Triggers emit to get full match context from server for a number of
// matches identified by their data_index.
let tmp_first_cpos = [];
let tmp_last_cpos = [];
for (let dataIndex of dataIndexes) {
tmp_first_cpos.push(results.data.matches[dataIndex].c[0]);
tmp_last_cpos.push(results.data.matches[dataIndex].c[1]);
}
nopaque.socket.emit("corpus_analysis_inspect_match",
{
type: resultsType,
data_indexes: dataIndexes,
first_cpos: tmp_first_cpos,
last_cpos: tmp_last_cpos,
});
}
} }
/** /**
* This class is used to create an SocketEventListener. * This class is used to create an SocketEventListener.
* Input are an identifying type string, the listener function and callbacks * Input are an identifying type string, the listener function and callbacks
* which will be executed as part of the listener function. The identifying * which will be executed as part of the listener function. The identifying
* type string is also used as the socket event event identifier. * type string is also used as the socket event event identifier.
*/ */
class SocketEventListener { class ClientEventListener {
constructor(type, listenerFunction, args=null) { constructor(type, listenerFunction) {
this.listenerCallbacks = {}; this.listenerCallbacks = {};
this.listenerFunction = listenerFunction; this.listenerFunction = listenerFunction;
this.type = type; this.type = type;
...@@ -127,8 +149,8 @@ class SocketEventListener { ...@@ -127,8 +149,8 @@ class SocketEventListener {
} }
} }
/** Shorthand to execute all registered callbacks with same args in insertion /** Shorthand to execute all registered callbacks with same defaultArgs
* order. * in insertion order.
* NOTE: * NOTE:
* Since ECMAScript 2015, objects do preserve creation order for * Since ECMAScript 2015, objects do preserve creation order for
* string and Symbol keys. In JavaScript engines that comply with the * string and Symbol keys. In JavaScript engines that comply with the
...@@ -136,11 +158,18 @@ class SocketEventListener { ...@@ -136,11 +158,18 @@ class SocketEventListener {
* yield the keys in order of insertion. * yield the keys in order of insertion.
* So all modern Browsers. * So all modern Browsers.
*/ */
executeCallbacks(payload) { executeCallbacks(defaultArgs) {
for (let [type, listenerCallback] of Object.entries(this.listenerCallbacks)) { for (let [type, listenerCallback] of Object.entries(this.listenerCallbacks)) {
listenerCallback.callbackFunction(payload, ...listenerCallback.args); listenerCallback.callbackFunction(...defaultArgs,
...listenerCallback.args);
} }
} }
// use this if you only want to execute a specific registered callback
executeCallback(defaultArgs, type) {
let listenerCallback = this.listenerCallbacks[type];
listenerCallback.callbackFunction(...defaultArgs,
...listenerCallback.args);
}
} }
/** /**
...@@ -159,6 +188,6 @@ class ListenerCallback { ...@@ -159,6 +188,6 @@ class ListenerCallback {
// export Classes from this module // export Classes from this module
export { export {
Client, Client,
SocketEventListener, ClientEventListener,
ListenerCallback, ListenerCallback,
}; };
\ No newline at end of file
...@@ -46,116 +46,24 @@ function saveQueryData(args) { ...@@ -46,116 +46,24 @@ function saveQueryData(args) {
} }
} }
function querySetup(payload, client) { function getResultsData(args) {
// deletes old data from query issued before this new query let [resultsType, dataIndexes, client, results, rest] = arguments;
client.results.clearAll(); client.notifyView('results-data-recieving');
// load necessary HTMLElements with selectory syntax and save them as fields client.getResultsData(resultsType, dataIndexes, results);
client.getHTMLElements(['#query-progress-bar', '#query-results-user-feedback',
'#recieved-match-count', '#total-match-count',
'#text-lookup-count', '#text-lookup-titles',
'#query-results-create', '#add-to-sub-results']);
client.recievedMatchCount.textContent = 0;
client.totalMatchCount.textContent = `${payload.match_count}`;
client.queryResultsUserFeedback.classList.toggle('hide');
client.queryProgressBar.classList.toggle('hide');
client.queryProgressBar.lastElementChild.style.width = '0%';
if (client.dynamicMode) {
client.addToSubResults.toggleAttribute('disabled');
client.queryResultsCreate.classList.toggle('disabled');
}
}
/**
* This callback should be registered to the SocketEventListener 'recieveQueryData'
* It takes the incoming chunk and renders the results using the
* results.jsList object. It can either handle live incoming data chunks or
* already loaded/imported results data.
*/
function queryRenderResults(payload, client) {
client.getHTMLElements(['#recieved-match-count', '#match-count',
'#display-options-form-expert_mode']);
const renderResults = (data) => {
/**
* resultItem saves the incoming chunk matches as objects to add those later
* to the client.results.jsList
*/
let resultItems = [];
// get infos for full match row
for (let [index, match] of data.matches.entries()) {
resultItems.push({...match, ...{'index': index + client.results.data.matches.length}});
}
client.results.jsList.add(resultItems, (items) => {
for (let item of items) {
item.elm = client.results.jsList.createResultRowElement(item, data);
}
});
}
if (client.dynamicMode) {
if (payload.chunk.cpos_ranges == true) {
client.results.data['cpos_ranges'] = true;
} else {
client.results.data['cpos_ranges'] = false;
}
renderResults(payload.chunk);
helperQueryRenderResults(payload, client);
console.info('Result progress is:', client.requestQueryProgress);
if (client.requestQueryProgress === 100) {
/**
* activate, hide or show elements if all reults have been recieved
* also load some new elements taht have not ben loaded before
*/
client.queryProgressBar.classList.toggle('hide');
client.queryResultsUserFeedback.classList.toggle('hide');
client.queryResultsCreate.classList.toggle('disabled');
client.addToSubResults.toggleAttribute('disabled');
// addToSubResultsElement.removeAttribute("disabled");
// // inital expert mode check and sub results activation
// client.results.jsList.activateInspect();
// if (addToSubResultsElement.checked) {
// client.results.jsList.activateAddToSubResults();
// }
// if (expertModeSwitchElement.checked) {
// client.results.jsList.expertModeOn("query-display");
// }
}
} else if (!client.dynamicMode) {
renderResults(payload);
helperQueryRenderResults({'chunk': payload}, client);
client.queryProgressBar.classList.toggle('hide');
client.queryResultsUserFeedback.classList.toggle('hide');
client.results.jsList.activateInspect();
if (client.displayOptionsFormExpertMode.checked) {
client.results.jsList.expertModeOn("query-display");
}
}
} }
/** function saveResultsData(args) {
* Helper function that saves result data into the client.results.data object. let [payload, client, results, rest] = arguments;
* Also does some showing and hiding of Elements and user feedback text. // code to save results data depending on type
*/ console.info('Results data has been saved.');
function helperQueryRenderResults (payload, client) { client.notifyView('results-data-recieved');
// updating table on finished item creation callback via createResultRowElement
client.results.jsList.update();
client.results.jsList.changeContext(); // sets lr context on first result load
// incorporating new chunk results into full results
client.results.data.matches.push(...payload.chunk.matches);
client.results.data.addData(payload.chunk.cpos_lookup, 'cpos_lookup');
client.results.data.addData(payload.chunk.text_lookup, 'text_lookup');
// complete metaData
// client.results.metaData.add();
// show user current and total match count
client.recievedMatchCount.textContent = `${client.results.data.matches.length}`;
client.textLookupCount.textContent = `${Object.keys(client.results.data.text_lookup).length}`;
let titles = new Array();
for (let [key, value] of Object.entries(client.results.data.text_lookup)) {
titles.push(`${value.title} (${value.publishing_year})`);
};
client.textLookupTitles.textContent = `${titles.join(", ")}`;
// update progress bar and requestQueryProgress
client.queryProgressBar.lastElementChild.style.width = `${payload.progress}%`;
client.requestQueryProgress = payload.progress;
} }
// export callbacks // export callbacks
export { prepareQueryData, saveMetaData, saveQueryData }; export {
\ No newline at end of file prepareQueryData,
saveMetaData,
saveQueryData,
getResultsData,
saveResultsData,
};
\ No newline at end of file
/** /**
* This file contains the listener functions which can be assigned to the * This file contains the listener functions which can be assigned to the
* coprus_analysis client. So that the incoming data/status informations will * coprus_analysis client. So that the incoming data/status informations will
* be handled. * be handled. There are several listeners listening for socket .io events.
* Further below one javascript custom event listener is specified. This
* listener listens for javascript custom events which are being dispatched by
* the View (resultsList).
*/ */
// Listeners for socket io events
/** /**
* Recieves a corpus analysis connected signal via socket.io. * Recieves a corpus analysis connected signal via socket.io.
*/ */
...@@ -50,7 +55,7 @@ function recieveMetaData(type, client) { ...@@ -50,7 +55,7 @@ function recieveMetaData(type, client) {
console.info(`corpus_analysis_meta_data: ${response.code} - ${response.msg}`); console.info(`corpus_analysis_meta_data: ${response.code} - ${response.msg}`);
console.info(response); console.info(response);
// executing the registered callbacks // executing the registered callbacks
client.socketEventListeners[type].executeCallbacks(response.payload); client.eventListeners[type].executeCallbacks([response.payload]);
console.groupEnd(); console.groupEnd();
} else { } else {
console.group('Failed to recieve meta data.'); console.group('Failed to recieve meta data.');
...@@ -81,7 +86,7 @@ function recieveQueryStatus(type, client) { ...@@ -81,7 +86,7 @@ function recieveQueryStatus(type, client) {
console.info(`corpus_analysis_query: ${response.code} - ${response.msg}`); console.info(`corpus_analysis_query: ${response.code} - ${response.msg}`);
console.info(response); console.info(response);
// executing the registered callbacks // executing the registered callbacks
client.socketEventListeners[type].executeCallbacks(response.payload); client.eventListeners[type].executeCallbacks([response.payload]);
console.groupEnd(); console.groupEnd();
} else { } else {
console.group('corpus_analysis_query: Client failed recieving', console.group('corpus_analysis_query: Client failed recieving',
...@@ -113,7 +118,7 @@ function recieveQueryData(type, client) { ...@@ -113,7 +118,7 @@ function recieveQueryData(type, client) {
/** /**
* Execute registered callbacks and notify View. * Execute registered callbacks and notify View.
*/ */
client.socketEventListeners[type].executeCallbacks(response.payload); client.eventListeners[type].executeCallbacks([response.payload]);
console.info('Added chunk data to results.data.'); console.info('Added chunk data to results.data.');
console.groupEnd(); console.groupEnd();
} else { } else {
...@@ -125,18 +130,72 @@ function recieveQueryData(type, client) { ...@@ -125,18 +130,72 @@ function recieveQueryData(type, client) {
} }
}); });
} else { } else {
console.group('corpus_analysis_query_results: Loading query data.') console.group('corpus_analysis_query_results: Loading query data.');
console.info('Client loading imported query data from database.'); console.info('Client loading imported query data from database.');
// executing the registered callbacks // executing the registered callbacks
client.socketEventListeners[type].executeCallbacks(); client.eventListeners[type].executeCallbacks();
console.groupEnd(); console.groupEnd();
} }
} }
/**
* Recieves the data requested by the create Results or sub results button
*/
function recieveResultsData(type, client) {
client.socket.on(type, (response) => {
/**
* Check if request for session was OK.
* If OK execute registered callbacks and notify View.
*/
if (response.code === 200) {
console.group('Client recieving results data')
console.info('corpus_analysis_inspect_match: Client recieving results data',
'via socket.on');
console.info(`corpus_analysis_inspect_match: ${response.code} - ${response.msg}`);
console.info(response);
// executing the registered callbacks
client.eventListeners[type].executeCallbacks([response.payload]);
console.groupEnd();
} else {
console.group('Failed to recieve results data.');
console.error('corpus_analysis_inspect_match: Client failed to recieve',
'results data via socket.on');
let errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
console.error(`corpus_analysis_inspect_match: ${errorText}`);
console.groupEnd();
}
});
}
/*
* This is the javascript custom event listener, listening for events
* dispatched by the View.
*/
function recieveViewNotification(type, client) {
document.addEventListener(type, (event) => {
let caseIdentifier = event.detail.caseIdentifier;
switch(caseIdentifier) {
case 'get-results':
console.info('Client getting full results for export.');
// execute callback or functions
client.eventListeners[type].executeCallback([event.detail.resultsType,
event.detail.dataIndexes],
caseIdentifier);
break
default:
console.error('Recieved unkown notification case identifier from View');
// do something to not crash the analysis session?
// maybe unnecessary
}
});
}
// export listeners from this module // export listeners from this module
export { export {
recieveConnected, recieveConnected,
recieveMetaData, recieveMetaData,
recieveQueryStatus, recieveQueryStatus,
recieveQueryData recieveQueryData,
recieveViewNotification,
recieveResultsData,
}; };
\ No newline at end of file
...@@ -8,6 +8,7 @@ class Results { ...@@ -8,6 +8,7 @@ class Results {
constructor() { constructor() {
this.data = new Data(); this.data = new Data();
this.metaData = new MetaData(); this.metaData = new MetaData();
this.fullResultsData = new Data();
this.subResultsData = new Data(); this.subResultsData = new Data();
console.info('Initialized the Results object.'); console.info('Initialized the Results object.');
} }
...@@ -15,12 +16,12 @@ class Results { ...@@ -15,12 +16,12 @@ class Results {
init() { init() {
this.data.init(); this.data.init();
this.metaData.init(); this.metaData.init();
this.fullResultsData = new Data();
this.subResultsData.init(); this.subResultsData.init();
} }
} }
class Data { class Data {
// Sets empty object structure. Also usefull to delete old results. // Sets empty object structure. Also usefull to delete old results.
// matchCount default is 0 // matchCount default is 0
...@@ -94,29 +95,6 @@ class Data { ...@@ -94,29 +95,6 @@ class Data {
this.download(downloadElement, dataStr, resultFilename, "text/json", ".json") this.download(downloadElement, dataStr, resultFilename, "text/json", ".json")
} }
// create results data either from all results or from al lmarked sub results
createResultsData(type) {
// deactivate inspect, because cqp server cannot handle multiple requests
results.jsList.deactivateInspect();
activateInspectInteraction.setCallback("noCheck",
results.jsList.deactivateInspect,
results.jsList);
// set flag that results are being created to avoid reactivation of
// sub results creation if marked matches are changed
resultCreationRunning = true;
console.log(resultCreationRunning);
if (type === "sub-results") {
resultsCreateElement.classList.add("disabled"); // cqp server cannot handle more than one request at a time. Thus we deactivate the resultsCreateElement
let tmp = [...results.jsList.addToSubResultsIdsToShow].sort(function(a, b){return a-b});
let dataIndexes = [];
tmp.forEach((index) => dataIndexes.push(index - 1));
results.jsList.getMatchWithContext(dataIndexes, "sub-results");
} else if (type === "results") {
subResultsCreateElement.classList.add("disabled"); // cqp server cannot handle more than one request at a time. Thus we deactivate the subResultsCreateElement
let dataIndexes = [...Array(results.data.match_count).keys()];
results.jsList.getMatchWithContext(dataIndexes, "results");
}
}
} }
class MetaData { class MetaData {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* This class implements a NotificationListener that is listening for the * This class implements a NotificationListener that is listening for the
* specified * specified
*/ */
class NotificationListener { class ViewEventListener {
constructor(type, listenerFunction) { constructor(type, listenerFunction) {
this.listenerFunction = listenerFunction; this.listenerFunction = listenerFunction;
this.type = type; this.type = type;
...@@ -61,7 +61,7 @@ class ResultsList extends List { ...@@ -61,7 +61,7 @@ class ResultsList extends List {
* class field in the ResultsList object with the query selector * class field in the ResultsList object with the query selector
* string as the key. The selector will be converted to a valid JavaScript * string as the key. The selector will be converted to a valid JavaScript
* Field name i. e. #html-id-string -> this.htmlIdString * Field name i. e. #html-id-string -> this.htmlIdString
* The value will be the identifed element fetched with the querySelector * The value will be the identifed element or elements fetched with the querySelector
* method. * method.
*/ */
// TODO: multipleResults=false, atattchSomeCallback=false ? // TODO: multipleResults=false, atattchSomeCallback=false ?
...@@ -73,6 +73,7 @@ class ResultsList extends List { ...@@ -73,6 +73,7 @@ class ResultsList extends List {
element = document.querySelector(selector); element = document.querySelector(selector);
} else { } else {
elements = document.querySelectorAll(selector); elements = document.querySelectorAll(selector);
elements = [...elements];
} }
let cleanKey = []; let cleanKey = [];
selector = selector.replace(/_/g, '-'); selector = selector.replace(/_/g, '-');
...@@ -106,6 +107,17 @@ class ResultsList extends List { ...@@ -106,6 +107,17 @@ class ResultsList extends List {
} }
} }
/**
* This functions sends events to the Client to trigger specific functions to
* trigger new data requests from the server.
*/
notifyClient(caseIdentifier, detailObject={}) {
detailObject.caseIdentifier = caseIdentifier;
const event = new CustomEvent('notify-client', { detail: detailObject });
console.info('Client dispatching Notification:', caseIdentifier);
document.dispatchEvent(event);
}
/** /**
* Creates cpos either from ranges or not. * Creates cpos either from ranges or not.
*/ */
...@@ -255,25 +267,6 @@ class ResultsList extends List { ...@@ -255,25 +267,6 @@ class ResultsList extends List {
} }
} }
// Triggers emit to get full match context from server for a number of
// matches identified by their data_index.
getMatchWithContext(dataIndexes, type) {
let tmp_first_cpos = [];
let tmp_last_cpos = [];
for (let dataIndex of dataIndexes) {
tmp_first_cpos.push(results.data.matches[dataIndex].c[0]);
tmp_last_cpos.push(results.data.matches[dataIndex].c[1]);
}
nopaque.socket.emit("corpus_analysis_inspect_match",
{
type: type,
data_indexes: dataIndexes,
first_cpos: tmp_first_cpos,
last_cpos: tmp_last_cpos,
}
);
}
// ###### Functions to inspect one match, to show more details ###### // ###### Functions to inspect one match, to show more details ######
// activate inspect buttons if progress is 100 // activate inspect buttons if progress is 100
activateInspect() { activateInspect() {
...@@ -786,7 +779,7 @@ class ResultsList extends List { ...@@ -786,7 +779,7 @@ class ResultsList extends List {
return matchRowElement return matchRowElement
} }
// creates the HTML table code for the metadata vie in the corpus analysis interface // creates the HTML table code for the metadata view in the corpus analysis interface
createMetaDataForModal(metaDataObject) { createMetaDataForModal(metaDataObject) {
let html = `<div class="col s12"> let html = `<div class="col s12">
<table class="highlight"> <table class="highlight">
...@@ -838,12 +831,12 @@ class ResultsList extends List { ...@@ -838,12 +831,12 @@ class ResultsList extends List {
} }
// Creates the text details for the texts shown in the corpus analysis metadata modal. // Creates the text details for the texts shown in the corpus analysis metadata modal.
createTextDetails(metaDataObject) { createTextDetails(metaData) {
let metadataKey = event.target.dataset.metadataKey; let metadataKey = event.target.dataset.metadataKey;
let textKey = event.target.dataset.textKey; let textKey = event.target.dataset.textKey;
let textData = metaDataObject[metadataKey][textKey]; let textData = metaData[metadataKey][textKey];
let bibliographicData = document.getElementById(`bibliographic-data-${metadataKey}-${textKey}`); let bibliographicData = document.querySelector(`#bibliographic-data-${metadataKey}-${textKey}`);
bibliographicData.innerHTML = ""; bibliographicData.textContent = '';
for (let [key, value] of Object.entries(textData)) { for (let [key, value] of Object.entries(textData)) {
bibliographicData.insertAdjacentHTML("afterbegin", bibliographicData.insertAdjacentHTML("afterbegin",
` `
...@@ -854,4 +847,4 @@ class ResultsList extends List { ...@@ -854,4 +847,4 @@ class ResultsList extends List {
}; };
// export classses // export classses
export { NotificationListener, ResultsList }; export { ViewEventListener, ResultsList };
\ No newline at end of file \ No newline at end of file
...@@ -98,8 +98,14 @@ function queryDataRecievedCallback(resultsList, detail) { ...@@ -98,8 +98,14 @@ function queryDataRecievedCallback(resultsList, detail) {
// show or enable some things for the user // show or enable some things for the user
resultsList.queryResultsCreate.classList.toggle('disabled'); resultsList.queryResultsCreate.classList.toggle('disabled');
resultsList.addToSubResults.removeAttribute("disabled"); resultsList.addToSubResults.removeAttribute("disabled");
}
function resultsDataRecievingCallback(resultsList, detail) {
// hide or disable elments taht would trigger another cqp data request
}
function resultsDataRecievedCallback(resultsList, detail) {
// hide or show the right stuff
} }
// export the callbacks // export the callbacks
...@@ -110,4 +116,6 @@ export { ...@@ -110,4 +116,6 @@ export {
queryDataPreparingCallback, queryDataPreparingCallback,
queryDataRecievingCallback, queryDataRecievingCallback,
queryDataRecievedCallback, queryDataRecievedCallback,
resultsDataRecievingCallback,
resultsDataRecievedCallback,
}; };
\ No newline at end of file
...@@ -14,43 +14,55 @@ import { ...@@ -14,43 +14,55 @@ import {
queryDataPreparingCallback, queryDataPreparingCallback,
queryDataRecievingCallback, queryDataRecievingCallback,
queryDataRecievedCallback, queryDataRecievedCallback,
resultsDataRecievingCallback,
resultsDataRecievedCallback,
} from './callbacks.js'; } from './callbacks.js';
function recieveNotification(eventType, resultsList) { function recieveClientNotification(eventType, resultsList) {
document.addEventListener(eventType, (event) => { document.addEventListener(eventType, (event) => {
let caseIdentifier = event.detail.caseIdentifier; let caseIdentifier = event.detail.caseIdentifier;
switch (caseIdentifier) { switch (caseIdentifier) {
case 'connecting': case 'connecting':
console.info('Recieved notification:', caseIdentifier); console.info('View recieved notification:', caseIdentifier);
connectingCallback(resultsList, event.detail); connectingCallback(resultsList, event.detail);
// execute callback // execute callback
break; break;
case 'connected': case 'connected':
console.info('Recieved notification:', caseIdentifier); console.info('View recieved notification:', caseIdentifier);
connectedCallback(resultsList, event.detail); connectedCallback(resultsList, event.detail);
break; break;
case 'connecting-failed': case 'connecting-failed':
console.info('Recieved notification:', caseIdentifier); console.info('View recieved notification:', caseIdentifier);
// execute callback // execute callback
connectingFaildeCallback(resultsList, event.detail); connectingFaildeCallback(resultsList, event.detail);
break; break;
case 'query-data-prepareing': case 'query-data-prepareing':
console.info('Recieved notification:', caseIdentifier); console.info('View recieved notification:', caseIdentifier);
// execute callback // execute callback
queryDataPreparingCallback(resultsList, event.detail); queryDataPreparingCallback(resultsList, event.detail);
break; break;
case 'query-data-recieving': case 'query-data-recieving':
console.info('Recieved notification:', caseIdentifier); console.info('View recieved notification:', caseIdentifier);
// execute callback // execute callback
queryDataRecievingCallback(resultsList, event.detail); queryDataRecievingCallback(resultsList, event.detail);
break; break;
case 'query-data-recieved': case 'query-data-recieved':
console.info('Recieved notification:', caseIdentifier); console.info('View recieved notification:', caseIdentifier);
// execute callback // execute callback
queryDataRecievedCallback(resultsList, event.detail); queryDataRecievedCallback(resultsList, event.detail);
break; break;
case 'results-data-recieving':
console.info('View recieved notification:', caseIdentifier);
// execute callback
resultsDataRecievedCallback(resultsList, event.detail);
break;
case 'results-data-recieved':
console.info('View recieved notification:', caseIdentifier);
// execute callback
resultsDataRecievedCallback(resultsList, event.detail);
break;
default: default:
console.error('Recieved unkown notification case identifier'); console.error('Recieved unkown notification case identifier from Client');
// do something to not crash the analysis session? // do something to not crash the analysis session?
// maybe unnecessary // maybe unnecessary
} }
...@@ -58,4 +70,4 @@ function recieveNotification(eventType, resultsList) { ...@@ -58,4 +70,4 @@ function recieveNotification(eventType, resultsList) {
} }
// export listeners // export listeners
export { recieveNotification }; export { recieveClientNotification };
\ No newline at end of file \ No newline at end of file
// loading spinner animation HTML
const loadingSpinnerHTML = `
<div class="preloader-wrapper button-icon-spinner small active">
<div class="spinner-layer spinner-green-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div><div class="gap-patch">
<div class="circle"></div>
</div><div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
`;
//export
export { loadingSpinnerHTML };
...@@ -70,35 +70,45 @@ ...@@ -70,35 +70,45 @@
* First Phase: * First Phase:
* Document content is loaded and scripts are being imported and executed. * Document content is loaded and scripts are being imported and executed.
*/ */
// import Client classes
import { import {
Client, Client,
SocketEventListener, ClientEventListener,
ListenerCallback, ListenerCallback,
} from '../../static/js/modules/corpus_analysis/client/Client.js'; } from '../../static/js/modules/corpus_analysis/client/Client.js';
// import client listener functions
import { import {
recieveConnected, recieveConnected,
recieveMetaData, recieveMetaData,
recieveQueryStatus, recieveQueryStatus,
recieveQueryData, recieveQueryData,
recieveViewNotification,
recieveResultsData,
} from '../../static/js/modules/corpus_analysis/client/listeners.js'; } from '../../static/js/modules/corpus_analysis/client/listeners.js';
import { // import client listener callbacks
Results,
} from '../../static/js/modules/corpus_analysis/model/Results.js';
import { import {
prepareQueryData, prepareQueryData,
saveQueryData, saveQueryData,
saveMetaData, saveMetaData,
getResultsData,
saveResultsData,
} from '../../static/js/modules/corpus_analysis/client/callbacks.js'; } from '../../static/js/modules/corpus_analysis/client/callbacks.js';
import { import {
NotificationListener, Results,
} from '../../static/js/modules/corpus_analysis/model/Results.js';
import {
ViewEventListener,
ResultsList, ResultsList,
} from '../../static/js/modules/corpus_analysis/view/ResultsView.js'; } from '../../static/js/modules/corpus_analysis/view/ResultsView.js';
import { import {
recieveNotification, recieveClientNotification,
} from '../../static/js/modules/corpus_analysis/view/listeners.js'; } from '../../static/js/modules/corpus_analysis/view/listeners.js';
import { import {
scrollToTop, scrollToTop,
} from '../../static/js/modules/corpus_analysis/view/scrollToTop.js' } from '../../static/js/modules/corpus_analysis/view/scrollToTop.js'
import {
loadingSpinnerHTML,
} from '../../static/js/modules/corpus_analysis/view/spinner.js'
/** /**
* Second Phase: * Second Phase:
...@@ -120,44 +130,59 @@ document.addEventListener("DOMContentLoaded", () => { ...@@ -120,44 +130,59 @@ document.addEventListener("DOMContentLoaded", () => {
let resultsList = new ResultsList('result-list', ResultsList.options); let resultsList = new ResultsList('result-list', ResultsList.options);
/** /**
* Register listeners listening to socket.io events and their callbacks * Register listeners listening to socket.io events and their callbacks
* Afterwards load them. * Afterwards load them. Also registers listeners listening for custom
* javascript events.
*/ */
const listenForConnected = new SocketEventListener('corpus_analysis_init', const listenForConnected = new ClientEventListener('corpus_analysis_init',
recieveConnected); recieveConnected);
const listenForMetaData = new SocketEventListener('corpus_analysis_meta_data', const listenForMetaData = new ClientEventListener('corpus_analysis_meta_data',
recieveMetaData); recieveMetaData);
const metaDataCallback = new ListenerCallback('corpus_analysis_meta_data', const metaDataCallback = new ListenerCallback('corpus_analysis_meta_data',
saveMetaData, saveMetaData,
[client, results]); [client, results]);
listenForMetaData.setCallbacks([metaDataCallback]); listenForMetaData.setCallbacks([metaDataCallback]);
const listenForQueryStatus = new SocketEventListener('corpus_analysis_query', const listenForQueryStatus = new ClientEventListener('corpus_analysis_query',
recieveQueryStatus); recieveQueryStatus);
const queryStatusCallback = new ListenerCallback('corpus_analysis_query', const queryStatusCallback = new ListenerCallback('corpus_analysis_query',
prepareQueryData, prepareQueryData,
[client, results]); [client, results]);
listenForQueryStatus.setCallbacks([queryStatusCallback]); listenForQueryStatus.setCallbacks([queryStatusCallback]);
const listenForQueryData = new SocketEventListener('corpus_analysis_query_results', const listenForQueryData = new ClientEventListener('corpus_analysis_query_results',
recieveQueryData); recieveQueryData);
const queryDataCallback = new ListenerCallback('corpus_analysis_query_results', const queryDataCallback = new ListenerCallback('corpus_analysis_query_results',
saveQueryData, saveQueryData,
[client, results]); [client, results]);
listenForQueryData.setCallbacks([queryDataCallback]); listenForQueryData.setCallbacks([queryDataCallback]);
const listenForResults = new ClientEventListener('corpus_analysis_inspect_match',
recieveResultsData);
const resultsDataCallback = new ListenerCallback('corpus_analysis_inspect_match',
saveResultsData,
[client, results]);
listenForResults.setCallbacks([resultsDataCallback]);
// listen for javascript custom notifications
const listenForViewNotification = new ClientEventListener('notify-client',
recieveViewNotification);
const getResultsCallback = new ListenerCallback('get-results',
getResultsData,
[client, results]);
listenForViewNotification.setCallbacks([getResultsCallback]);
client.setSocketEventListeners([listenForConnected, client.setSocketEventListeners([listenForConnected,
listenForQueryStatus, listenForQueryStatus,
listenForQueryData, listenForQueryData,
listenForMetaData]); listenForMetaData,
listenForViewNotification,
listenForResults]);
client.loadSocketEventListeners(); client.loadSocketEventListeners();
/** /**
* Register resultsList listeners listening to nitification events. * Register resultsList listeners listening to nitification events.
*/ */
const listenForNotification = new NotificationListener('notify', const listenForClientNotification = new ViewEventListener('notify-view',
recieveNotification); recieveClientNotification);
resultsList.setNotificationListeners([listenForNotification]); resultsList.setNotificationListeners([listenForClientNotification]);
resultsList.loadNotificationListeners(); resultsList.loadNotificationListeners();
// Connect client to server // Connect client to server
client.notifyView('connecting'); client.notifyView('connecting');
client.connect(); client.connect();
// Send a query and recieve its answer data // Send a query and recieve its answer data
let queryFormElement = document.querySelector('#query-form'); let queryFormElement = document.querySelector('#query-form');
queryFormElement.addEventListener('submit', (event) => { queryFormElement.addEventListener('submit', (event) => {
...@@ -181,20 +206,66 @@ document.addEventListener("DOMContentLoaded", () => { ...@@ -181,20 +206,66 @@ document.addEventListener("DOMContentLoaded", () => {
results.data.getQueryStr(queryFormElement); results.data.getQueryStr(queryFormElement);
client.query(results.data.query); client.query(results.data.query);
}); });
/** // Get all needed HTMLElements for the following event listeners
* Display events
* 1. live update of hits per page if hits per page value is changed
*/
resultsList.getHTMLElements([ resultsList.getHTMLElements([
'#display-options-form-results_per_page', '#display-options-form-results_per_page',
'#display-options-form-result_context' '#display-options-form-result_context',
'#show-meta-data',
'#meta-data-modal',
'#meta-data-modal-content',
'#query-results-create'
]); ]);
/**
* Display events: Following event listeners are handleing the
* live update of hits per page if hits per page value is changed and the
* context size of every match.
*/
resultsList.displayOptionsFormResultsPerPage.onchange = () => { resultsList.displayOptionsFormResultsPerPage.onchange = () => {
resultsList.changeHitsPerPage(); resultsList.changeHitsPerPage();
}; };
resultsList.displayOptionsFormResultContext.onchange = () => { resultsList.displayOptionsFormResultContext.onchange = () => {
resultsList.changeContext(); resultsList.changeContext();
}; };
/**
* The following event listener handel the Show metadata button and its
* functionality. Before the needed modal is initialized.
*/
let deleteOverlay = () => {
let overlay = document.querySelector(".modal-overlay");
overlay.remove();
};
resultsList.metaDataModal= M.Modal.init(resultsList.metaDataModal, {
'preventScrolling': false,
'opacity': 0.0,
'dismissible': false,
'onOpenEnd': deleteOverlay
});
resultsList.showMetaData.onclick = () => {
resultsList.metaDataModalContent.textContent = '';
let table = resultsList.createMetaDataForModal(results.metaData);
resultsList.metaDataModalContent.insertAdjacentHTML('afterbegin', table);
resultsList.metaDataModal.open();
let collapsibles = resultsList.metaDataModalContent.querySelectorAll(".text-metadata");
for (let collapsible of collapsibles) {
collapsible.onclick = () => {
let elems = resultsList.metaDataModalContent.querySelectorAll('.collapsible');
let instances = M.Collapsible.init(elems, {accordion: false});
resultsList.createTextDetails(results.metaData);
}
}
};
/**
* The following event listeners are handeling the data export.
*/
resultsList.queryResultsCreate.onclick = () => {
resultsList.queryResultsCreate.querySelector('i').classList.toggle('hide');
resultsList.queryResultsCreate.innerText = 'Creating...';
resultsList.queryResultsCreate.insertAdjacentHTML('afterbegin',
loadingSpinnerHTML);
resultsList.notifyClient('get-results', { resultsType: 'full-results',
dataIndexes: [...Array(results.data.match_count).keys()]});
}
......
...@@ -7,7 +7,7 @@ result.--> ...@@ -7,7 +7,7 @@ result.-->
<div class="divider" style="margin-bottom: 10px;"></div> <div class="divider" style="margin-bottom: 10px;"></div>
<div class="row"> <div class="row">
<div class="col s12"> <div class="col s12">
<button id="show-metadata" <button id="show-meta-data"
class="waves-effect class="waves-effect
waves-light waves-light
btn-flat btn-flat
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment