Add more old functionality

This commit is contained in:
Stephan Porada 2020-09-07 16:30:47 +02:00
parent 0eda40d0e7
commit 521fd72d9b
9 changed files with 151 additions and 102 deletions

View File

@ -102,11 +102,12 @@ class Client {
this.socket.emit('corpus_analysis_query', queryStr);
}
// create results data either from all results or from all marked sub results
/**
* Create results data either from all results or from all marked sub results
* Triggers emit to get full match context from server for a number of
* matches identified by their data_index.
**/
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) {
@ -168,7 +169,7 @@ class ClientEventListener {
/**
* This class is used to create an ListenerCallback which will be registered
* to an SocketEventListener so the Listener cann invoke the ListenerCallback
* to an SocketEventListener so the Listener can invoke the ListenerCallback
* callback functions.
*/
class ListenerCallback {

View File

@ -65,6 +65,7 @@ function saveResultsData(args) {
objectKey = 'inspectResultsData'
console.info('Saving inspect-results data');
}
// Save incoming data
results[objectKey].init();
results[objectKey].matches.push(...payload.matches);
results[objectKey].addData(payload.cpos_lookup, "cpos_lookup");
@ -75,7 +76,8 @@ function saveResultsData(args) {
results[objectKey].match_count = [...payload.matches].length;
results[objectKey].cpos_ranges = payload.cpos_ranges;
console.info('Results data has been saved.', results);
client.notifyView('results-data-recieved', {type: type});
client.notifyView('results-data-recieved', {type: type,
results: results});
}
// export callbacks

View File

@ -1,4 +1,10 @@
class InteractionElement {
// TODO: Simplify this so that things are executed on change page and on first
// load look below at function doc strings
// one interaction can have more than one type when the associatee callback
// can be executed
class Interaction {
constructor(htmlId="",
checkStatus=true,
disabledBefore=true,
@ -6,14 +12,15 @@ class InteractionElement {
hideBefore=true,
hideAfter=false) {
this.htmlId = htmlId;
this.element = (htmlId) => {this.element = document.getElementById(htmlId);}
this.element = ((htmlId) => {
document.getElementById(htmlId);
})()
this.checkStatus = checkStatus;
this.callbacks = {};
this.disabledBefore = disabledBefore;
this.disabledAfter = disabledAfter;
this.hideBefore = hideBefore;
this.hideAfter = hideAfter;
this.element(this.htmlId);
}
setCallback(trigger, callback, bindThis, args=[]) {
@ -31,16 +38,22 @@ class InteractionElement {
}
}
class InteractionElements {
class Interactions {
constructor() {
this.interactions = [];
}
addInteractions (interactionsArray) {
this.interactions.push(...interactionsArray);
addInteractions (interactions) {
this.interactions.push(...interactions);
}
onChangeExecute() {
/**
* This function executes all registered interactions of the type
* onElementChange.
* Interactions and their associated callbacks will be executed every time
* a chante event occurs on the specified element.
*/
onElementChangeExecute() {
// checks if a change for every interactionElement happens and executes
// the callbacks accordingly
for (let interaction of this.interactions) {
@ -61,6 +74,23 @@ class InteractionElements {
}
};
}
/**
* This function executes all registered interactions of the type onQueryLoad.
* Interactions and their associated callbacks will be executed once if when
* the first query results of a query request are being displayed.
*/
onQueryLoadExecute() {
}
/**
* This function executes all registered interactions of the type
* onPageChange.
* Interactions and their associated callbacks will be executed everytime if
* the user used the page navigation and a new result page is being displayed.
*/
onPageChangeExecute() {
}
}
// export Classes

View File

@ -48,6 +48,7 @@ class ResultsList extends List {
* here to delete later on
*/
this.currentExpertTokenElements = {};
// TODO: Rename both variables to something more descreptive and clear
// holds True/false for check buttons used to add matches tu sub-results. If checked, it is True. If unchecked, it is false. Buttons for this have the class add. Those little round check buttons.
this.addToSubResultsStatus = {};
this.addToSubResultsIdsToShow = new Set(); // If check button is pressed its corresponding data_index is saved in this set. The set is shown to the user.
@ -57,9 +58,10 @@ class ResultsList extends List {
}
/**
* // TODO:
* Init function that gets all needed HTML Elements. Implement this, or not?
* Or build a check into the get HTMLElements function if element already exists.
* Also think aobut saving alle elements in resultsList.es.nameOfElement
* Also think about saving alle elements in resultsList.es.nameOfElement
*/
/**
@ -239,16 +241,22 @@ class ResultsList extends List {
} else if ([...this.addToSubResultsIdsToShow].length === 0) {
this.subResultsCreate.classList.toggle('disabled', true);
}
// After a match as been added or removed the export button will be
// hidden because the sub-results have been altered and have to be built
// again. Thus subResultsCreateElement has to be shown again.
/**
* After a match as been added or removed the export button will be
* hidden because the sub-results have been altered and have to be built
* again. Thus subResultsCreateElement has to be shown again.
*/
this.subResultsExport.classList.add("hide");
this.subResultsCreate.classList.remove("hide");
// Also activate/deactivate buttons in the table/jsList results accordingly
//if button in inspect was activated/deactivated.
// This part only runs if tableCall is false.
/**
* Also activate/deactivate buttons in the table/jsList results accordingly
* if button in inspect was activated/deactivated.
* This part only runs if tableCall is false.
*/
if (!tableCall) {
let tableAddBtn = document.getElementById('query-results').querySelectorAll(`[data-index="${dataIndex}"]`)[0].getElementsByClassName('add')[0].firstElementChild; // gets the add button from the list view
this.getHTMLElements(['#query-results-table']);
let container = this.queryResultsTable.querySelector(`[data-index="${dataIndex}"]`);
let tableAddBtn = container.querySelector('.add-btn'); // gets the add button from the list view
if (this.addToSubResultsStatus[dataIndex]) {
this.helperActivateAddBtn(tableAddBtn);
} else {
@ -325,8 +333,11 @@ class ResultsList extends List {
// the server
inspect(dataIndex, type) {
// initialize context modal
this.getHTMLElements(['#context-modal',
'#context-results']);
this.getHTMLElements([
'#context-modal',
'#context-results',
'#create-inspect-menu',
]);
this.contextModal = M.Modal.init(this.contextModal);
// get result infos from server and show them in context modal
this.contextId = dataIndex[0];
@ -344,18 +355,15 @@ class ResultsList extends List {
addToSubResultsIdsBtn.setAttribute("class", classes + ` add`);
addToSubResultsIdsBtn.innerHTML = '<i class="material-icons">add</i>';
addToSubResultsIdsBtn.onclick= () => {this.addToSubResults(dataIndex[0], false)};
// // checks if a button has already been added to the inspect modal and removes it
// if (addToSubResultsFromInspectElement.children.length > 0) {
// addToSubResultsFromInspectElement.firstElementChild.remove();
// }
// // Changes the design of the add button according to its checked status
// // upon opening the inspect modal.
// if (this.addToSubResultsStatus[dataIndex[0]]) {
// this.helperActivateAddBtn(addToSubResultsIdsBtn.firstElementChild);
// } else if (!this.addToSubResultsStatus[dataIndex[0]]) {
// this.helperDeactivateAddBtn(addToSubResultsIdsBtn.firstElementChild);
// }
// addToSubResultsFromInspectElement.appendChild(addToSubResultsIdsBtn);
// checks if the match has or has not been added to sub results yet
// sets the color and status of the button accordingly
if (this.addToSubResultsStatus[dataIndex[0]]) {
this.helperActivateAddBtn(addToSubResultsIdsBtn.firstElementChild);
} else if (!this.addToSubResultsStatus[dataIndex[0]]) {
this.helperDeactivateAddBtn(addToSubResultsIdsBtn.firstElementChild);
}
this.createInspectMenu.innerHTML = '';
this.createInspectMenu.appendChild(addToSubResultsIdsBtn);
}
// create Element from HTML String helper function
@ -369,42 +377,26 @@ class ResultsList extends List {
// Used as a callback to handle incoming match context results when inspect
// has been used.
showMatchContext(response) {
this.contextData;
let contextModalLoading;
let contextModalReady;
let contextResultsElement;
let highlightSentencesSwitchElement;
let htmlTokenStr;
let modalExpertModeSwitchElement;
let modalTokenElements;
let nrOfContextSentences;
let partElement;
let token;
let tokenHTMLArray;
let tokenHTMlElement;
let uniqueContextS;
let uniqueS;
showMatchContext(results) {
this.contextData = response.payload;
this.contextData["cpos_ranges"] = response.payload.cpos_ranges;
this.contextData["query"] = results.data.query;
this.contextData["context_id"] = this.contextId;
this.contextData["match_count"] = this.contextData.matches.length
this.contextData["corpus_type"] = "inspect-result"
Object.assign(this.contextData, results.metaData);
contextResultsElement = document.getElementById("context-results");
modalExpertModeSwitchElement = document.getElementById("inspect-display-options-form-expert_mode_inspect");
highlightSentencesSwitchElement = document.getElementById("inspect-display-options-form-highlight_sentences");
nrOfContextSentences = document.getElementById("context-sentences");
uniqueS = new Set();
uniqueContextS = new Set();
let {lc, c, rc} = this.helperCreateCpos(this.contextData.cpos_ranges,
this.contextData.matches[0])
this.getHTMLElements([
'#context-results',
'#inspect-display-options-form-expert_mode_inspect',
'#inspect-display-options-form-highlight_sentences',
'#context-sentences'
])
let uniqueS = new Set();
let uniqueContextS = new Set();
let {lc, c, rc} = this.helperCreateCpos(results.inspectResultsData.cpos_ranges,
results.inspectResultsData.matches[0]);
// create sentence strings as tokens
tokenHTMLArray = [];
let tokenHTMLArray = [];
let htmlTokenStr = ``;
let tokenHTMlElement;
let token;
for (let cpos of lc) {
token = this.contextData.cpos_lookup[cpos];
token = results.inspectResultsData.cpos_lookup[cpos];
uniqueS.add(token.s)
htmlTokenStr = `<span class="token"` +
`data-sid="${token.s}"` +
@ -415,7 +407,7 @@ class ResultsList extends List {
tokenHTMLArray.push(tokenHTMlElement);
}
for (let cpos of c) {
token = this.contextData.cpos_lookup[cpos];
token = results.inspectResultsData.cpos_lookup[cpos];
uniqueContextS.add(token.s);
uniqueS.add(token.s);
htmlTokenStr = `<span class="token bold light-green"` +
@ -427,9 +419,9 @@ class ResultsList extends List {
tokenHTMlElement = this.HTMLTStrToElement(htmlTokenStr)
tokenHTMLArray.push(tokenHTMlElement);
}
this.contextData["context_s_ids"] = Array.from(uniqueContextS);
results.inspectResultsData["context_s_ids"] = Array.from(uniqueContextS);
for (let cpos of rc) {
token = this.contextData.cpos_lookup[cpos];
token = results.inspectResultsData.cpos_lookup[cpos];
uniqueS.add(token.s)
htmlTokenStr = `<span class="token"` +
`data-sid="${token.s}"` +
@ -450,20 +442,20 @@ class ResultsList extends List {
continue;
}
}
contextResultsElement.appendChild(sentenceElement);
this.contextResults.appendChild(sentenceElement);
}
// add inspect display options events
modalExpertModeSwitchElement.onchange = (event) => {
this.inspectDisplayOptionsFormExpertModeInspect.onchange = (event) => {
if (event.target.checked) {
this.expertModeOn("context-results");
this.expertModeOn("context-results", results);
} else {
this.expertModeOff("context-results")
}
};
highlightSentencesSwitchElement.onchange = (event) => {
this.inspectDisplayOptionsFormHighlightSentences.onchange = (event) => {
if (event.target.checked) {
this.higlightContextSentences();
} else {
@ -471,24 +463,24 @@ class ResultsList extends List {
}
};
nrOfContextSentences.onchange = (event) => {
this.contextSentences.onchange = (event) => {
// console.log(event.target.value);
this.changeSentenceContext(event.target.value);
}
// checks on new modal opening if switches are checked
// if switches are checked functions are executed
if (modalExpertModeSwitchElement.checked) {
this.expertModeOn("context-results");
if (this.inspectDisplayOptionsFormExpertModeInspect.checked) {
this.expertModeOn("context-results", results);
}
if (highlightSentencesSwitchElement.checked) {
if (this.inspectDisplayOptionsFormHighlightSentences.checked) {
this.higlightContextSentences();
}
// checks the value of the number of sentences to show on modal opening
// sets context sentences accordingly
this.changeSentenceContext(nrOfContextSentences.value)
this.changeSentenceContext(this.contextSentences.value);
}
// splits context text into sentences based on spacy sentence split
@ -597,24 +589,25 @@ class ResultsList extends List {
// ###### Expert view event functions ######
// function to create a tooltip for the current hovered token
tooltipEventCreate(event, client) {
tooltipEventCreate(event, results) {
// console.log("Create Tooltip on mouseover.");
let token = client.results.data.cpos_lookup[event.target.dataset.cpos];
let token;
token = results.data.cpos_lookup[event.target.dataset.cpos];
if (!token) {
token = this.contextData.cpos_lookup[event.target.dataset.cpos];
token = results.inspectResultsData.cpos_lookup[event.target.dataset.cpos];
}
this.addToolTipToTokenElement(event.target, token, client);
this.addToolTipToTokenElement(event.target, token, results);
}
// Function to destroy the current Tooltip for the current hovered tooltip
// on mouse leave
tooltipEventDestroy() {
tooltipEventDestroy(event) {
// console.log("Tooltip destroy on leave.");
this.currentTooltipElement.destroy();
}
// turn the expert mode on for all tokens in the DOM element identified by its htmlID
expertModeOn(htmlId, client) {
expertModeOn(htmlId, results) {
if (!Array.isArray(this.currentExpertTokenElements[htmlId])) {
this.currentExpertTokenElements[htmlId] = [];
}
@ -625,15 +618,15 @@ class ResultsList extends List {
for (let tokenElement of this.currentExpertTokenElements[htmlId]) {
tokenElement.classList.add("chip", "hoverable", "expert-view");
const eventCreate = (event, arg) => this.tooltipEventCreate(event, arg);
tokenElement.onmouseover = (event) => eventCreate(event, client);
tokenElement.onmouseout = () => this.tooltipEventDestroy();
tokenElement.onmouseover = (event) => eventCreate(event, results);
tokenElement.onmouseout = (event) => this.tooltipEventDestroy(event);
this.eventTokens[htmlId].push(tokenElement);
}
}
// fuction that creates Tooltip for one token and extracts the corresponding
// infos from the result JSON
addToolTipToTokenElement(tokenElement, token, client) {
addToolTipToTokenElement(tokenElement, token, results) {
this.currentTooltipElement;
this.currentTooltipElement = M.Tooltip.init(tokenElement,
{"html": `<table>
@ -650,11 +643,11 @@ class ResultsList extends List {
NER: ${token.ner}
</td>
<td class="left-align">
Title: ${client.results.data.text_lookup[token.text].title}
Title: ${results.data.text_lookup[token.text].title}
<br>
Author: ${client.results.data.text_lookup[token.text].author}
Author: ${results.data.text_lookup[token.text].author}
<br>
Publishing year: ${client.results.data.text_lookup[token.text].publishing_year}
Publishing year: ${results.data.text_lookup[token.text].publishing_year}
</td>
</tr>
</table>`}

View File

@ -133,6 +133,7 @@ function resultsDataRecievingCallback(resultsList, detail) {
function resultsDataRecievedCallback(resultsList, detail) {
resultsList.clientIsBusy = false;
// create strings for create buttons depending on type
const handleType = (keyPrefix, text) => {
// hides the create element after results have been recieved and reset it
resultsList[`${keyPrefix}Create`].classList.toggle('hide');
@ -151,6 +152,15 @@ function resultsDataRecievedCallback(resultsList, detail) {
handleType('fullResults', 'Results');
} else if (detail.type ==='sub-results') {
handleType('subResults', 'Sub-Results');
} else if (detail.type ==='inspect-results') {
if (resultsList.addToSubResultsIdsToShow.size === 0) {
/**
* Prevent create sub results button from being activated if it is disabled
* and no matches have been marked by the user for sub results creation.
*/
resultsList.subResultsCreate.classList.toggle('disabled', true);
}
resultsList.showMatchContext(detail.results);
}
}

View File

@ -72,8 +72,8 @@ function recieveClientNotification(eventType, resultsList) {
console.info('View recieved notification:', caseIdentifier);
// execute callbacks
console.info(event.detail);
resultsDataRecievedCallback(resultsList, event.detail);
enableElementsGeneralCallback(resultsList, event.detail);
resultsDataRecievedCallback(resultsList, event.detail);
break;
default:
console.error('Recieved unkown notification case identifier from Client');

View File

@ -219,8 +219,20 @@ document.addEventListener("DOMContentLoaded", () => {
'#sub-results-export',
'#download-results-json',
'#query-results-download-modal',
'#query-results-table'
'#query-results-table',
'#display-options-form-expert_mode',
]);
/**
* The following event Listener handles the expert mode switch for the list
*/
resultsList.displayOptionsFormExpertMode.onchange = (event) => {
if (event.target.checked) {
resultsList.expertModeOn('query-display', results);
} else {
resultsList.expertModeOff('query-display');
}
};
/**
* The following event Listener handles the add-btn and the inspect-btn
* onclick events via bubbleing.
@ -235,8 +247,9 @@ document.addEventListener("DOMContentLoaded", () => {
resultsList.addToSubResults(dataIndex);
}
})
/**
* Display events: Following event listeners are handleing the
* Display events: Following event listeners are handling the
* live update of hits per page if hits per page value is changed and the
* context size of every match.
*/
@ -246,6 +259,7 @@ document.addEventListener("DOMContentLoaded", () => {
resultsList.displayOptionsFormResultContext.onchange = () => {
resultsList.changeContext();
};
/**
* The following event listener handel the Show metadata button and its
* functionality. Before the needed modal is initialized.
@ -270,7 +284,7 @@ document.addEventListener("DOMContentLoaded", () => {
}
}
};
resultsList.addToSubResults.on
/**
* The following event listeners are handeling the data export.
* 1. Create full-results

View File

@ -8,7 +8,7 @@
<div class="section">
<h6 style="margin-top: 0px;">Display</h6>
<div class="divider" style="margin-bottom: 10px;"></div>
<div class="col s12" style="margin-bottom: 10px;" id="display-inspect">
<div class="col s12" style="margin-bottom: 10px;">
{{ inspect_display_options_form.expert_mode_inspect.label.text }}
<div class="switch right">
<label>
@ -17,7 +17,7 @@
</label>
</div>
</div>
<div class="col s12" style="margin-bottom: 10px;" id="create-inspect">
<div class="col s12" style="margin-bottom: 10px;">
{{ inspect_display_options_form.highlight_sentences.label.text }}
<div class="switch right">
<label>
@ -42,19 +42,18 @@
</div>
</div>
</div>
{% if not imported %}
<div class="col s12 m6 l6">
<div class="section">
<h6 style="margin-top: 0px;">Create</h6>
<div class="divider" style="margin-bottom: 10px;"></div>
<div class="col s12">
Add to Sub Results
<div class="secondary-content right" id="add-to-sub-results-from-inspect">
<div class="secondary-content right" id="create-inspect-menu">
{# The needed button is created and added via javascript #}
</div>
</div>
</div>
</div>
{% endif %}
</div>
</form>
<div class="row section">