From ead0117bbb5bac54c56affae088b50388099a5b1 Mon Sep 17 00:00:00 2001 From: Stephan Porada Date: Fri, 19 Jun 2020 15:49:11 +0200 Subject: [PATCH] More Analysis Javascript updates for unified interaction handeling --- web/app/corpora/events.py | 24 ++++-- .../static/js/nopaque.CorpusAnalysisClient.js | 16 +++- .../static/js/nopaque.InteractionElement.js | 4 +- web/app/static/js/nopaque.callbacks.js | 5 ++ web/app/static/js/nopaque.lists.js | 78 ++++++++++++------- .../templates/corpora/analyse_corpus.html.j2 | 78 ++++++++++--------- 6 files changed, 130 insertions(+), 75 deletions(-) diff --git a/web/app/corpora/events.py b/web/app/corpora/events.py index b148839e..fa40115f 100644 --- a/web/app/corpora/events.py +++ b/web/app/corpora/events.py @@ -128,10 +128,15 @@ def corpus_analysis_query(query): @socketio.on('corpus_analysis_inspect_match') @socketio_login_required def corpus_analysis_inspect_match(payload): + type = payload['type'] + data_index = payload["data_index"] client = corpus_analysis_clients.get(request.sid) if client is None: - response = {'code': 424, 'desc': 'No client found for this session', - 'msg': 'Failed Dependency'} + response = {'code': 424, + 'desc': 'No client found for this session', + 'msg': 'Failed Dependency', + 'type': type, + 'data_index': data_index} socketio.emit('corpus_analysis_inspect_match', response, room=request.sid) return @@ -143,10 +148,19 @@ def corpus_analysis_inspect_match(payload): payload['cpos_ranges'] = True except cqi.errors.CQiException as e: payload = {'code': e.code, 'desc': e.description, 'msg': e.name} - response = {'code': 500, 'desc': None, 'msg': 'Internal Server Error', - 'payload': payload} + response = {'code': 500, + 'desc': None, + 'msg': 'Internal Server Error', + 'payload': payload, + 'type': type, + 'data_index': data_index} else: - response = {'code': 200, 'desc': None, 'msg': 'OK', 'payload': payload} + response = {'code': 200, + 'desc': None, + 'msg': 'OK', + 'payload': payload, + 'type': type, + 'data_index': data_index} socketio.emit('corpus_analysis_inspect_match', response, room=request.sid) diff --git a/web/app/static/js/nopaque.CorpusAnalysisClient.js b/web/app/static/js/nopaque.CorpusAnalysisClient.js index 5e60f3a7..31db4e84 100644 --- a/web/app/static/js/nopaque.CorpusAnalysisClient.js +++ b/web/app/static/js/nopaque.CorpusAnalysisClient.js @@ -86,9 +86,19 @@ class CorpusAnalysisClient { } }); + // inspect callback handeling based on type socket.on("corpus_analysis_inspect_match", (response) => { - if (this.callbacks.query_match_context != undefined) { - this.callbacks.query_match_context(response); + if (response.type === "inspect") { + if (this.callbacks.query_match_context != undefined) { + this.callbacks.query_match_context(response); + } + } else if (response.type === "sub-subcorpus"){ + if (this.callbacks.show_sub_subcorpus_choices != undefined) { + this.callbacks.show_sub_subcorpus_choices(response); + } + if (this.callbacks.save_sub_subcorpus_choices != undefined) { + this.callbacks.save_sub_subcorpus_choices(response); + } } }); } @@ -104,7 +114,7 @@ class CorpusAnalysisClient { } getMetaData() { - // just emits thos to tell the server to gather all meta dat infos and send + // just emits thos to tell the server to gather all meta data infos and send // those back this.socket.emit("corpus_analysis_get_meta_data", this.corpusId); } diff --git a/web/app/static/js/nopaque.InteractionElement.js b/web/app/static/js/nopaque.InteractionElement.js index 477fd243..5d8c1f05 100644 --- a/web/app/static/js/nopaque.InteractionElement.js +++ b/web/app/static/js/nopaque.InteractionElement.js @@ -1,10 +1,12 @@ class InteractionElement { constructor(htmlId="", + checkStatus=true, disabledBefore=true, disabledAfter=false, hideBefore=true, hideAfter=false) { this.htmlId = htmlId; + this.checkStatus = checkStatus; this.callbacks = {}; this.disabledBefore = disabledBefore; this.disabledAfter = disabledAfter; @@ -14,7 +16,7 @@ class InteractionElement { getElement() { this.interactionStatusElement = document.getElementById(this.htmlId); - return this.interactionStatusElement + return this.interactionStatusElement; } setCallback(trigger, callback, bindThis, args=[]) { diff --git a/web/app/static/js/nopaque.callbacks.js b/web/app/static/js/nopaque.callbacks.js index e26c3985..cbf8cf0b 100644 --- a/web/app/static/js/nopaque.callbacks.js +++ b/web/app/static/js/nopaque.callbacks.js @@ -3,6 +3,11 @@ function recvMetaData(payload) { console.log(results.metaData); } +function saveSubSubcorpusChoices(payload) { + console.log("SAVE"); + console.log(payload); +} + function querySetup(payload) { // This is called when a query was successfull // some hiding and resetting diff --git a/web/app/static/js/nopaque.lists.js b/web/app/static/js/nopaque.lists.js index 5354fc69..10f446b2 100644 --- a/web/app/static/js/nopaque.lists.js +++ b/web/app/static/js/nopaque.lists.js @@ -141,17 +141,24 @@ class ResultsList extends List { pageChangeEventInteractionHandler(interactionElements) { // get elements to check thier status for (let interaction of interactionElements) { - let element = interaction.getElement(); - if (element.checked) { - let f_on = interaction.bindThisToCallback("on"); - let args_on = interaction.callbacks.on.args; - f_on(...args_on); - console.log("ON TRIGGERED"); + if (interaction.checkStatus) { + let element = interaction.getElement(); + if (element.checked) { + let f_on = interaction.bindThisToCallback("on"); + let args_on = interaction.callbacks.on.args; + f_on(...args_on); + console.log("ON TRIGGERED"); + } else { + let f_off = interaction.bindThisToCallback("off"); + let args_off = interaction.callbacks.off.args; + f_off(...args_off); + console.log("OFF TRIGGERED"); + } } else { - let f_off = interaction.bindThisToCallback("off"); - let args_off = interaction.callbacks.off.args; - f_off(...args_off); - console.log("OFF TRIGGERED"); + let f = interaction.bindThisToCallback("noCheck"); + let args = interaction.callbacks.noCheck.args; + f(...args); + console.log("noCheck activated"); } } } @@ -174,11 +181,9 @@ class ResultsList extends List { // ###### Functions to add one match to a sub-subcorpus ###### // activate add button activateAddToSubSubcorpus() { - if (progress === 100) { - let addToSubSubcorpusBtnElements = document.getElementsByClassName("add"); - for (let addToSubSubcorpusBtn of addToSubSubcorpusBtnElements) { - addToSubSubcorpusBtn.classList.remove("hide"); - } + let addToSubSubcorpusBtnElements = document.getElementsByClassName("add"); + for (let addToSubSubcorpusBtn of addToSubSubcorpusBtnElements) { + addToSubSubcorpusBtn.classList.remove("hide"); } } // deactivate add button @@ -192,12 +197,16 @@ class ResultsList extends List { addToSubSubcorpus(dataIndex) { if (!this.addToSubSubcorpuStatus[dataIndex] || this.addToSubSubcorpuStatus === undefined) { + // add button is activated + nopaque.flash(`[Match ${dataIndex + 1}] Marked for Sub-Subcorpus!`); event.target.classList.remove("grey"); event.target.classList.add("green"); event.target.innerText = "check"; this.addToSubSubcorpuStatus[dataIndex] = true; - console.log(dataIndex); + this.getMatchWithContext(dataIndex, "sub-subcorpus"); } else if (this.addToSubSubcorpuStatus[dataIndex]) { + // add button is deactivated + nopaque.flash(`[Match ${dataIndex + 1}] Unmarked for Sub-Subcorpus!`); event.target.classList.remove("green"); event.target.classList.add("grey"); event.target.innerText = "add"; @@ -205,11 +214,33 @@ class ResultsList extends List { } } + // handels incoming match info from socket on event + showSubSubcorpusChoices(response) { + console.log("SHOW"); + console.log(response.data_index); + } + + // gets full info for one match + getMatchWithContext(dataIndex, type) { + this.contextId = dataIndex; + let contextResultsElement; + contextResultsElement = document.getElementById("context-results"); + contextResultsElement.innerHTML = ""; // clear it from old inspects + nopaque.socket.emit("corpus_analysis_inspect_match", + { + type: type, + data_index: dataIndex, + first_cpos: results.data.matches[dataIndex].c[0], + last_cpos: results.data.matches[dataIndex].c[1], + } + ); + } + // ###### Functions to inspect one match, to show more details ###### // activate inspect buttons if progress is 100 activateInspect() { - let inspectBtnElements; if (progress === 100) { + let inspectBtnElements; inspectBtnElements = document.getElementsByClassName("inspect"); for (let inspectBtn of inspectBtnElements) { inspectBtn.classList.remove("disabled"); @@ -221,17 +252,8 @@ class ResultsList extends List { //gets result cpos infos for one dataIndex to send back to the server inspect(dataIndex, type) { - this.contextId = dataIndex; - let contextResultsElement; - contextResultsElement = document.getElementById("context-results"); - contextResultsElement.innerHTML = ""; // clear it from old inspects + this.getMatchWithContext(dataIndex, type); contextModal.open(); - nopaque.socket.emit("corpus_analysis_inspect_match", - {"type": type, - first_cpos: results.data.matches[dataIndex].c[0], - last_cpos: results.data.matches[dataIndex].c[1], - } - ); } // create Element from HTML String helper function @@ -633,7 +655,7 @@ class ResultsList extends List { // add some interaction buttons // # some btn css rules and classes let css = `margin-right: 10px;` - let classes = `btn-floating btn-flat waves-effect` + + let classes = `btn-floating btn waves-effect` + `waves-light grey right` // # add button to trigger more context to every match td inspectBtn = document.createElement("a"); diff --git a/web/app/templates/corpora/analyse_corpus.html.j2 b/web/app/templates/corpora/analyse_corpus.html.j2 index bc49037f..f6745587 100644 --- a/web/app/templates/corpora/analyse_corpus.html.j2 +++ b/web/app/templates/corpora/analyse_corpus.html.j2 @@ -404,7 +404,13 @@ }); client.setCallback("query_match_context", (payload) => { results.jsList.showMatchContext(payload); - }) + }); + client.setCallback("show_sub_subcorpus_choices", (payload) => { + results.jsList.showSubSubcorpusChoices(payload); + }); + client.setCallback("save_sub_subcorpus_choices", (payload) => { + saveSubSubcorpusChoices(payload); + }); // Trigger corpus analysis initialization on server side client.init(); @@ -443,7 +449,6 @@ // stuff that happens in the list table and should also be checked and // updated if the pagination is used - interactionElements = new Array(); let expertModeInteraction = new InteractionElement("display-options-form-expert_mode"); expertModeInteraction.setCallback("on", @@ -454,6 +459,7 @@ results.jsList.expertModeOff, results.jsList, ["query-display"]) + let subSubcorpusInteraction = new InteractionElement("add-to-sub-subcorpus"); subSubcorpusInteraction.setCallback("on", results.jsList.activateAddToSubSubcorpus, @@ -461,16 +467,25 @@ subSubcorpusInteraction.setCallback("off", results.jsList.deactivateAddToSubSubcorpus, results.jsList); - interactionElements.push(expertModeInteraction, subSubcorpusInteraction); + + let activateInspectInteraction = new InteractionElement("inspect", + false); + activateInspectInteraction.setCallback("noCheck", + results.jsList.activateInspect, + results.jsList); + + let changeContextInteraction = new InteractionElement("display-options-form-results_per_page", + false); + changeContextInteraction.setCallback("noCheck", + results.jsList.changeContext, + results.jsList) + interactionElements.push(expertModeInteraction, subSubcorpusInteraction, activateInspectInteraction, changeContextInteraction); // eventListener if pagination is used to apply new context size to new page // and also activate inspect match if progress is 100 // also adds more interaction buttons like add to subcorpus for (let element of paginationElements) { - element.addEventListener("click", results.jsList.changeContext); - element.addEventListener("click", results.jsList.activateInspect); - element.addEventListener("click", results.jsList.activateAddToSubSubcorpus); element.addEventListener("click", (event) => { results.jsList.pageChangeEventInteractionHandler(interactionElements); }); @@ -479,36 +494,23 @@ // checks if a change for every interactionElement happens and executes // the callbacks accordingly for (let interaction of interactionElements) { - let element = interaction.getElement() - element.addEventListener("change", (event) => { - if (event.target.checked) { - let f_on = interaction.bindThisToCallback("on"); - let args_on = interaction.callbacks.on.args; - f_on(...args_on); - } else { - let f_off = interaction.bindThisToCallback("off"); - let args_off = interaction.callbacks.off.args; - f_off(...args_off); - } - }); + if (interaction.checkStatus) { + let element = interaction.getElement() + element.addEventListener("change", (event) => { + if (event.target.checked) { + let f_on = interaction.bindThisToCallback("on"); + let args_on = interaction.callbacks.on.args; + f_on(...args_on); + } else { + let f_off = interaction.bindThisToCallback("off"); + let args_off = interaction.callbacks.off.args; + f_off(...args_off); + } + }); + } else { + continue + } }; - - // Show add buttons for sub-subcorpus creation if this is pressed - // addToSubSubcorpusElement.addEventListener("change", (event) => { - // if (event.target.checked) { - // results.jsList.activateAddToSubSubcorpus(); - // } else { - // results.jsList.deActivateAddToSubSubcorpus(); - // } - // }); - - // expertModeSwitchElement.addEventListener("change", (event) => { - // if (event.target.checked) { - // results.jsList.expertModeOn("query-display"); - // } else { - // results.jsList.expertModeOff("query-display"); - // } - // }); }); // Add onclick to open download modal when Export Results button is pressed @@ -530,8 +532,8 @@ let filename = results.data.createDownloadFilename(`context-id-${results.jsList.contextId}`); results.data.addData(results.metaData); results.data.downloadJSONRessource(filename, - results.jsList.contextData, - downloadInspectContextElement); - }; + results.jsList.contextData, + downloadInspectContextElement); +}; {% endblock %}