mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-10-30 02:11:13 +00:00 
			
		
		
		
	Remove baks before merge
This commit is contained in:
		| @@ -1,205 +0,0 @@ | ||||
| class CorpusAnalysisClient { | ||||
|   constructor(corpusId, socket) { | ||||
|     this.callbacks = {}; | ||||
|     this.corpusId = corpusId; | ||||
|     this.displays = {}; | ||||
|     this.socket = socket; | ||||
|  | ||||
|     // socket on event for corpous analysis initialization | ||||
|     socket.on("corpus_analysis_init", (response) => { | ||||
|       let errorText; | ||||
|  | ||||
|       if (response.code === 200) { | ||||
|         console.log(`corpus_analysis_init: ${response.code} - ${response.msg}`); | ||||
|         if (this.callbacks.init != undefined) { | ||||
|           this.callbacks.init(response.payload); | ||||
|           this.callbacks.get_metadata();  // should hold the function getMetaData | ||||
|         } | ||||
|         if (this.displays.init != undefined) { | ||||
|           this.displays.init.setVisibilityByStatus("success"); | ||||
|         } | ||||
|       } else { | ||||
|         errorText = `Error ${response.code} - ${response.msg}`; | ||||
|         if (this.displays.init.errorContainer != undefined)  { | ||||
|           this.displays.init.errorContainer.innerHTML = `<p class="red-text">` + | ||||
|                    `<i class="material-icons tiny">error</i> ${errorText}</p>`; | ||||
|         } | ||||
|         if (this.displays.init != undefined)  { | ||||
|           this.displays.init.setVisibilityByStatus("error"); | ||||
|         } | ||||
|         console.error(`corpus_analysis_init: ${errorText}`); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     // socket on event for recieving meta | ||||
|     socket.on('corpus_analysis_send_meta_data', (response) => { | ||||
|       let errorText; | ||||
|  | ||||
|       if (response.code === 200) { | ||||
|         console.log(`corpus_analysis_send_meta_data: ${response.code} - ${response.msg} - ${response.desc}`); | ||||
|         if (this.callbacks.recv_meta_data != undefined) { | ||||
|           this.callbacks.recv_meta_data(response.payload); | ||||
|         } | ||||
|       } else { | ||||
|         errorText = `Error ${response.code} - ${response.msg}`; | ||||
|         if (this.displays.init.errorContainer != undefined)  { | ||||
|           this.displays.init.errorContainer.innerHTML = `<p class="red-text">` + | ||||
|                    `<i class="material-icons tiny">error</i> ${errorText}</p>`; | ||||
|         } | ||||
|         if (this.displays.init != undefined)  { | ||||
|           this.displays.init.setVisibilityByStatus("error"); | ||||
|         } | ||||
|         console.error(`corpus_analysis_send_meta_data: ${errorText}`); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     // socket on event for recieveing query results | ||||
|     socket.on("corpus_analysis_query", (response) => { | ||||
|       let errorText; | ||||
|  | ||||
|       if (response.code === 200) { | ||||
|         console.log(`corpus_analysis_query: ${response.code} - ${response.msg}`); | ||||
|         if (this.callbacks.query != undefined)  { | ||||
|           this.callbacks.query(response.payload); | ||||
|         } | ||||
|         if (this.displays.query != undefined)  { | ||||
|           this.displays.query.setVisibilityByStatus("success"); | ||||
|         } | ||||
|       } else { | ||||
|         errorText = `Error ${response.payload.code} - ${response.payload.msg}`; | ||||
|         nopaque.flash(errorText, "error"); | ||||
|         if (this.displays.query.errorContainer != undefined)  { | ||||
|           this.displays.query.errorContainer.innerHTML = `<p class="red-text">`+ | ||||
|                     `<i class="material-icons tiny">error</i> ${errorText}</p>`; | ||||
|         } | ||||
|         if (this.displays.query != undefined)  { | ||||
|           this.displays.query.setVisibilityByStatus("error"); | ||||
|         } | ||||
|         console.error(`corpus_analysis_query: ${errorText}`); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|  | ||||
|     socket.on("corpus_analysis_query_results", (response) => { | ||||
|         if (this.callbacks.query_results != undefined) { | ||||
|           this.callbacks.query_results(response.payload); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     // inspect callback handeling based on type | ||||
|     socket.on("corpus_analysis_inspect_match", (response) => { | ||||
|       console.log(response); | ||||
|       if (response.type === "inspect") { | ||||
|         if (this.callbacks.query_match_context != undefined) { | ||||
|           this.callbacks.query_match_context(response); | ||||
|         } | ||||
|       } else if (response.type === "sub-results" | ||||
|                  || response.type ==="results"){ | ||||
|         if (this.callbacks.save_sub_results_choices != undefined) { | ||||
|           this.callbacks.save_sub_results_choices(response); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   init() { | ||||
|     if (this.displays.init.errorContainer != undefined)  { | ||||
|       this.displays.init.errorContainer.innerHTML == ""; | ||||
|     } | ||||
|     if (this.displays.init != undefined)  { | ||||
|       this.displays.init.setVisibilityByStatus("waiting"); | ||||
|     } | ||||
|     this.socket.emit("corpus_analysis_init", this.corpusId); | ||||
|   } | ||||
|  | ||||
|   getMetaData() { | ||||
|     // just emits this to tell the server to gather all meta data infos and send | ||||
|     // those back | ||||
|     this.socket.emit("corpus_analysis_get_meta_data", this.corpusId); | ||||
|   } | ||||
|  | ||||
|   query(queryStr) { | ||||
|     let displayOptionsData; | ||||
|     let resultListOptions; | ||||
|  | ||||
|     if (this.displays.query.errorContainer != undefined)  { | ||||
|       this.displays.query.errorContainer.innerHTML == ""; | ||||
|     } | ||||
|     if (this.displays.query != undefined)  { | ||||
|       this.displays.query.setVisibilityByStatus("waiting"); | ||||
|     } | ||||
|     nopaque.socket.emit("corpus_analysis_query", queryStr); | ||||
|   } | ||||
|  | ||||
|   setCallback(type, callback) { | ||||
|     // saves callback functions into an object. Key is function type, callback | ||||
|     // is the callback function | ||||
|     this.callbacks[type] = callback; | ||||
|   } | ||||
|  | ||||
|   setDisplay(type, display) { | ||||
|     this.displays[type] = display; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| class CorpusAnalysisDisplay { | ||||
|   constructor(element) { | ||||
|     this.element = element; | ||||
|     this.errorContainer = element.querySelector(".error-container"); | ||||
|     this.showOnError = element.querySelectorAll(".show-on-error"); | ||||
|     this.showOnSuccess = element.querySelectorAll(".show-on-success"); | ||||
|     this.showWhileWaiting = element.querySelectorAll(".show-while-waiting"); | ||||
|     this.hideOnComplete = element.querySelectorAll(".hide-on-complete") | ||||
|   } | ||||
|  | ||||
|   setVisibilityByStatus(status) { | ||||
|     switch (status) { | ||||
|       case "error": | ||||
|         for (let element of this.showOnError) { | ||||
|           element.classList.remove("hide"); | ||||
|         } | ||||
|         for (let element of this.showOnSuccess) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         for (let element of this.showWhileWaiting) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         break; | ||||
|       case "success": | ||||
|         for (let element of this.showOnError) { | ||||
|           element.classList.add("hide"); | ||||
|  | ||||
|         } | ||||
|         for (let element of this.showOnSuccess) { | ||||
|           element.classList.remove("hide"); | ||||
|         } | ||||
|         for (let element of this.showWhileWaiting) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         break; | ||||
|       case "waiting": | ||||
|         for (let element of this.showOnError) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         for (let element of this.showOnSuccess) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         for (let element of this.showWhileWaiting) { | ||||
|           element.classList.remove("hide"); | ||||
|         } | ||||
|         break; | ||||
|       default: | ||||
|         // Hide all | ||||
|         for (let element of this.showOnError) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         for (let element of this.showOnSuccess) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|         for (let element of this.showWhileWaiting) { | ||||
|           element.classList.add("hide"); | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -1,440 +0,0 @@ | ||||
| {% extends "nopaque.html.j2" %} | ||||
|  | ||||
| {% set headline = ' ' %} | ||||
|  | ||||
| {% set full_width = True %} | ||||
| {% set imported = False %} | ||||
|  | ||||
| {% block page_content %} | ||||
| <div class="col s12"> | ||||
|   <div class="card"> | ||||
|     <div class="card-content" style="padding-top: 5px; | ||||
|                              padding-bottom: 0px;"> | ||||
|       <!-- Query form --> | ||||
|       <div class="row"> | ||||
|       <form id="query-form"> | ||||
|           <div class="col s12 m10"> | ||||
|             <div class="input-field"> | ||||
|               <i class="material-icons prefix">search</i> | ||||
|               {{ query_form.query() }} | ||||
|               {{ query_form.query.label }} | ||||
|               <span class="helper-text"> | ||||
|                 <a href="http://cwb.sourceforge.net/files/CQP_Tutorial/"> | ||||
|                   <i class="material-icons" style="font-size: inherit;">help | ||||
|                   </i> | ||||
|                   CQP query language tutorial | ||||
|                 </a> | ||||
|               </span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col s12 m2 right-align"> | ||||
|             <br class="hide-on-small-only"> | ||||
|             {{ M.render_field(query_form.submit, material_icon='send') }} | ||||
|           </div> | ||||
|       </form> | ||||
|     </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| <!-- entire results div/card --> | ||||
| <div class="col s12" id="query-display"> | ||||
|   <div class="card"> | ||||
|     <div class="card-content" id="result-list" style="overflow: hidden;"> | ||||
|       <div class="error-container hide show-on-error"></div> | ||||
|       <div class=" row hide show-on-success"> | ||||
|         {% include 'interactions/infos.html.j2' %} | ||||
|         {% include 'interactions/export.html.j2' %} | ||||
|         {% include 'interactions/create.html.j2' %} | ||||
|         {% include 'interactions/display.html.j2' %} | ||||
|         {% include 'interactions/analysis.html.j2' %} | ||||
|         {% include 'interactions/cite.html.j2' %} | ||||
|       </div> | ||||
|       {% include 'tables/query_results.html.j2' %} | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| <!-- Scroll to top element --> | ||||
| {% include 'interactions/scroll_to_top.html.j2' %} | ||||
|  | ||||
| <!-- Modals --> | ||||
| {% include 'modals/show_metadata.html.j2' %} | ||||
| {% include 'modals/show_text_details.html.j2' %} | ||||
| {% include 'modals/analysis_init.html.j2' %} | ||||
| {% include 'modals/export_query_results.html.j2' %} | ||||
| {% include 'modals/context_modal.html.j2' %} | ||||
|  | ||||
|  | ||||
| <script src="{{ url_for('static', filename='js/nopaque.CorpusAnalysisClient.js') }}"> | ||||
| </script> | ||||
| <script src="{{ url_for('static', filename='js/nopaque.Results.js') }}"> | ||||
| </script> | ||||
| <script src="{{ url_for('static', filename='js/nopaque.callbacks.js') }}"> | ||||
| </script> | ||||
| <script src="{{ url_for('static', filename='js/nopaque.InteractionElement.js') }}"> | ||||
| </script> | ||||
| <script> | ||||
| // ###### Defining global variables used in other functions ###### | ||||
|   var addToSubResultsElement; // Button to start adding matches to sub-results | ||||
|   var addToSubResultsFromInspectElement; // button in inspect mdoal to add this match to the sub results | ||||
|   var client;  // CorpusAnalysisClient first undefined on DOMContentLoaded defined | ||||
|   var collapsibleElements;  // All collapsibleElements on this page | ||||
|   var contextModal;  // Modal to open on inspect for further match context | ||||
|   var data;  // full JSON object holding match results | ||||
|   var expertModeSwitchElement; // Expert mode switch Element | ||||
|   var initDisplay;  // CorpusAnalysisDisplay object first undfined on DOMContentLoaded defined | ||||
|   var interactionElements;  // Interaction elements and their parameters | ||||
|   var matchCountElement;  // Total nr. of matches will be displayed in this element | ||||
|   var progress;  // global progress value | ||||
|   var queryDisplay; // CorpusAnalysisDisplay object first undfined on DOMContentLoaded defined | ||||
|   var queryFormElement;  // the query form | ||||
|   var queryResultsDeterminateElement;  // The progress bar for recieved results | ||||
|   var resultsExportElement;  // Download button opens download modal | ||||
|   var queryResultsProgressElement;  // Div element holding the progress bar | ||||
|   var queryResultsUserFeedbackElement;  // Element showing match count|total etc | ||||
|   var receivedMatchCountElement;  // Nr. of loaded matches will be displayed in this element | ||||
|   var results;  // results object | ||||
|   var resultsList;  // resultsList object | ||||
|   var resultsListOptions;  // specifies ResultsList options | ||||
|   var subResultsCreateElement; // if pressed sub results will be created from ids | ||||
|   var resultsCreateElement; // if pressed results will pe created for all matches | ||||
|   var subResultsExportElement;  // button to download sub results | ||||
|   var subResultsIdListElement;  // list showing marked matches for sub corpus creation | ||||
|   var textLookupCountElement  // Nr of texts the matches occured in will be shown in this element | ||||
|   var textTitlesElement;  // matched text titles | ||||
|   var nrMarkedMatches;  // count of matches marked for subresults | ||||
|   var showMetaDataButton;  // Button to show corpus metadata | ||||
|   var activateInspectInteraction;  // global interaction element | ||||
|   var expertModeInteraction;  // global interaction element | ||||
|   var subResultsInteraction;  // global interaction element | ||||
|   var changeContextInteraction;  // global interaction element | ||||
|   var resultCreationRunning; | ||||
|  | ||||
|   // ###### Defining local scope variables ###### | ||||
|   let contextPerItemElement;  // Form Element for display option | ||||
|   let contextSentencesElement;  // Form Element for display option in inspect | ||||
|   let displayOptionsData;  // Getting form data from display options | ||||
|   let displayOptionsFormElement;  // Form holding the display informations | ||||
|   let downloadResultsJSONElement;  // button for downloading results as JSON | ||||
|   let downloadInspectContextElement;  // button for downloading inspect context | ||||
|   let exportModal;  // Download options modal | ||||
|   let firstPageElement;  // first page element of resultsList pagination | ||||
|   let hitsPerPageInputElement; | ||||
|   let initDisplayElement;  // Element for initialization using initDisplay | ||||
|   let initModal; | ||||
|   let paginationElements; | ||||
|   let queryDisplayElement;  // Element for initialization using queryDisplay | ||||
|   let xpath;  // xpath to grab first resultsList page pagination element | ||||
|   let metaDataModal;  // modal showing corpus meta data | ||||
|  | ||||
|   // ###### Initialize variables ###### | ||||
|   addToSubResultsElement = document.getElementById("add-to-sub-results"); | ||||
|   addToSubResultsFromInspectElement = document.getElementById("add-to-sub-results-from-inspect"); | ||||
|   client = undefined; | ||||
|   collapsibleElements = document.querySelector('.collapsible.expandable'); | ||||
|   contextModal = document.getElementById("context-modal"); | ||||
|   contextPerItemElement = document.getElementById("display-options-form-result_context"); | ||||
|   contextSentencesElement = document.getElementById("context-sentences"); | ||||
|   displayOptionsFormElement = document.getElementById("display-options-form"); | ||||
|   expertModeSwitchElement = document.getElementById("display-options-form-expert_mode"); | ||||
|   exportModal = document.getElementById("query-results-download-modal"); | ||||
|   hitsPerPageInputElement = document.getElementById("display-options-form-results_per_page"); | ||||
|   initDisplay = undefined; | ||||
|   initDisplayElement = document.getElementById("init-display"); | ||||
|   matchCountElement = document.getElementById("match-count"); | ||||
|   paginationElements = document.getElementsByClassName("pagination"); | ||||
|   queryDisplay = undefined; | ||||
|   queryDisplayElement = document.getElementById("query-display"); | ||||
|   queryFormElement = document.getElementById("query-form"); | ||||
|   queryResultsDeterminateElement = document.getElementById("query-results-determinate"); | ||||
|   resultsExportElement = document.getElementById("query-results-export"); | ||||
|   queryResultsProgressElement = document.getElementById("query-results-progress"); | ||||
|   queryResultsUserFeedbackElement = document.getElementById("query-results-user-feedback"); | ||||
|   receivedMatchCountElement = document.getElementById("received-match-count"); | ||||
|   subResultsCreateElement = document.getElementById("sub-results-create"); | ||||
|   resultsCreateElement = document.getElementById("results-create"); | ||||
|   subResultsExportElement = document.getElementById("sub-results-export"); | ||||
|   subResultsIdListElement = document.getElementById("sub-results-match-ids-div"); | ||||
|   textLookupCountElement = document.getElementById("text-lookup-count"); | ||||
|   textTitlesElement = document.getElementById("text-titles"); | ||||
|   nrMarkedMatches = document.getElementById("nr-marked-matches"); | ||||
|   showMetaDataButton = document.getElementById("show-metadata"); | ||||
|   metaDataModal = document.getElementById("meta-data-modal"); | ||||
|  | ||||
|   // ###### js list options and intialization ###### | ||||
|   displayOptionsData = ResultsList.getDisplayOptions(displayOptionsFormElement); | ||||
|   resultsListOptions = {page: displayOptionsData["resultsPerPage"], | ||||
|     pagination: [{ | ||||
|       name: "paginationTop", | ||||
|       paginationClass: "paginationTop", | ||||
|       innerWindow: 8, | ||||
|       outerWindow: 1 | ||||
|     }, { | ||||
|       paginationClass: "paginationBottom", | ||||
|       innerWindow: 8, | ||||
|       outerWindow: 1 | ||||
|     }], | ||||
|     valueNames: ["titles", "lc", "c", "rc", {data: ["index"]}], | ||||
|     item: `<span></span>`}; | ||||
|  | ||||
|  | ||||
|   // ###### event on DOMContentLoaded ###### | ||||
|   document.addEventListener("DOMContentLoaded", () => { | ||||
|     // creates some modals on DOMContentLoaded | ||||
|     let defaultOptions = {"dismissible": true, | ||||
|                           "preventScrolling": false}; | ||||
|     contextModal = M.Modal.init(contextModal, defaultOptions); | ||||
|     exportModal = M.Modal.init(exportModal, defaultOptions); | ||||
|     initModal = M.Modal.init(initDisplayElement, {"dismissible": false}); | ||||
|     let deleteOverlay = () => { | ||||
|       let overlay = document.getElementsByClassName("modal-overlay")[0]; | ||||
|       overlay.remove(); | ||||
|     }; | ||||
|     metaDataModal = M.Modal.init(metaDataModal, {"preventScrolling": false, | ||||
|                                  "opacity": 0.0, | ||||
|                                  "dismissible": false, | ||||
|                                  "onOpenEnd": deleteOverlay}); | ||||
|     // Init corpus analysis components | ||||
|     data = new Data(); | ||||
|     resultsList = new ResultsList("result-list", resultsListOptions); | ||||
|     resultsMetaData = new MetaData(); | ||||
|     results = new Results(data, resultsList, resultsMetaData); | ||||
|     initDisplay = new CorpusAnalysisDisplay(initDisplayElement); | ||||
|     queryDisplay = new CorpusAnalysisDisplay(queryDisplayElement); | ||||
|     client = new CorpusAnalysisClient({{ corpus_id }}, nopaque.socket); | ||||
|     initModal.open(); | ||||
|  | ||||
|     // set displays and callback functions | ||||
|     client.setDisplay("init", initDisplay); | ||||
|     client.setCallback("init", () => { | ||||
|       initModal.close(); | ||||
|     }); | ||||
|     client.setCallback('get_metadata', () => { | ||||
|       client.getMetaData(); | ||||
|     }) | ||||
|     client.setCallback('recv_meta_data', (response) => { | ||||
|       recvMetaData(response); | ||||
|     }) | ||||
|     client.setDisplay("query", queryResultsUserFeedbackElement); | ||||
|     client.setDisplay("query", queryDisplay); | ||||
|     client.setCallback("query", (payload) => { | ||||
|       querySetup(payload); | ||||
|     }); | ||||
|     client.setCallback("query_results", (payload) => { | ||||
|       queryRenderResults(payload); | ||||
|     }); | ||||
|     client.setCallback("query_match_context", (payload) => { | ||||
|       results.jsList.showMatchContext(payload); | ||||
|     }); | ||||
|     client.setCallback("save_sub_results_choices", (payload) => { | ||||
|       saveSubResultsChoices(payload); | ||||
|     }); | ||||
|  | ||||
|     // Trigger corpus analysis initialization on server side | ||||
|     client.init(); | ||||
|     // start a query request on submit | ||||
|     queryFormElement.addEventListener("submit", (event) => { | ||||
|       try { | ||||
|         // Selects first page of result list if pagination is already available | ||||
|         // from an query submitted before. | ||||
|         // This avoids confusion for the user eg: The user was on page 24 | ||||
|         // reviewing the results and issues a new query. He would not see any | ||||
|         // results until the new results reach page 24 or he clicks on another | ||||
|         // valid result page element from the new pagination. | ||||
|         firstPageElement; | ||||
|         xpath = '//a[@class="page" and text()=1]'; | ||||
|         firstPageElement = document.evaluate(xpath, | ||||
|                                              document, | ||||
|                                              null, | ||||
|                                              XPathResult.FIRST_ORDERED_NODE_TYPE, | ||||
|                                              null).singleNodeValue; | ||||
|         firstPageElement.click(); | ||||
|       } catch (e) { | ||||
|       } | ||||
|       // Prevent page from reloading on submit | ||||
|       event.preventDefault(); | ||||
|       // Get query string and send query to server | ||||
|       results.data.getQueryStr(queryFormElement); | ||||
|       client.query(results.data.query); | ||||
|     }); | ||||
|  | ||||
|     // live update of hits per page if hits per page value is changed | ||||
|     let changeHitsPerPageBind = results.jsList.changeHitsPerPage.bind(results.jsList); | ||||
|     hitsPerPageInputElement.onchange = changeHitsPerPageBind; | ||||
|  | ||||
|     // live update of lr context per item if context value is changed | ||||
|     contextPerItemElement.onchange = results.jsList.changeContext; | ||||
|  | ||||
|     // Initialization of interactionElemnts | ||||
|     // An interactionElement is an object identifing a switch or button via | ||||
|     // htmlID. Callbacks are set for these elements which will be triggered on | ||||
|     // a pagination interaction by the user or if the status of the element has | ||||
|     // been altered. (Like the switche has ben turned on or off). | ||||
|     interactionElements = new InteractionElements(); | ||||
|     expertModeInteraction = new InteractionElement("display-options-form-expert_mode"); | ||||
|     expertModeInteraction.setCallback("on", | ||||
|                                       results.jsList.expertModeOn, | ||||
|                                       results.jsList, | ||||
|                                       ["query-display"]) | ||||
|     expertModeInteraction.setCallback("off", | ||||
|                                       results.jsList.expertModeOff, | ||||
|                                       results.jsList, | ||||
|                                       ["query-display"]) | ||||
|  | ||||
|     subResultsInteraction = new InteractionElement("add-to-sub-results"); | ||||
|     subResultsInteraction.setCallback("on", | ||||
|                                         results.jsList.activateAddToSubResults, | ||||
|                                         results.jsList); | ||||
|     subResultsInteraction.setCallback("off", | ||||
|                                         results.jsList.deactivateAddToSubResults, | ||||
|                                         results.jsList); | ||||
|  | ||||
|     activateInspectInteraction = new InteractionElement("inspect", | ||||
|                                                             false); | ||||
|     activateInspectInteraction.setCallback("noCheck", | ||||
|                                             results.jsList.activateInspect, | ||||
|                                             results.jsList); | ||||
|  | ||||
|     changeContextInteraction = new InteractionElement("display-options-form-results_per_page", | ||||
|                                                           false); | ||||
|     changeContextInteraction.setCallback("noCheck", | ||||
|                                         results.jsList.changeContext, | ||||
|                                         results.jsList) | ||||
|     interactionElements.addInteractions([expertModeInteraction, subResultsInteraction, activateInspectInteraction, changeContextInteraction]); | ||||
|  | ||||
|     // checks if a change for every interactionElement happens and executes | ||||
|     // the callbacks accordingly | ||||
|     interactionElements.onChangeExecute(); | ||||
|  | ||||
|     // 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 sub results | ||||
|     for (let element of paginationElements) { | ||||
|       element.addEventListener("click", (event) => { | ||||
|         results.jsList.pageChangeEventInteractionHandler(interactionElements); | ||||
|       }); | ||||
|     } | ||||
|  | ||||
|     // ### Show corpus Metadata | ||||
|     showMetaDataButton.onclick = () => { | ||||
|       let metaDataObject = {}; | ||||
|       Object.assign(metaDataObject, results.metaData); | ||||
|       metaDataObject["query"] = results.data.query; | ||||
|       metaDataObject["text_lookup"] = results.data.text_lookup; | ||||
|       metaDataModalContent = document.getElementById("meta-data-modal-content"); | ||||
|       metaDataModalContent.innerHTML = ""; | ||||
|       let table = results.jsList.createMetaDataForModal(metaDataObject); | ||||
|       metaDataModalContent.insertAdjacentHTML("afterbegin", table); | ||||
|       metaDataModal.open(); | ||||
|       let collapsibles = document.getElementsByClassName("text-metadata"); | ||||
|       for (let collapsible of collapsibles) { | ||||
|         collapsible.onclick = () => { | ||||
|           let elems = document.querySelectorAll('.collapsible'); | ||||
|           let instances = M.Collapsible.init(elems, {accordion: false}); | ||||
|           results.jsList.createTextDetails(metaDataObject); | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|   }); | ||||
|  | ||||
|   // new insepct event listener makeing use of javascript bubbleing | ||||
|   let resultsTable = document.getElementById("query-results"); | ||||
|   console.log(resultsTable); | ||||
|   resultsTable.addEventListener("click", (event) => { | ||||
|     let dataIndex; | ||||
|     if (event.target.classList.contains("inspect-btn")) { | ||||
|       dataIndex = parseInt(event.target.closest("tr").dataset.index); | ||||
|       console.log(dataIndex); | ||||
|       results.jsList.inspect([dataIndex], "inspect"); | ||||
|     } else if (event.target.classList.contains("add-btn")) { | ||||
|       dataIndex = parseInt(event.target.closest("tr").dataset.index); | ||||
|       results.jsList.addToSubResults(dataIndex); | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   // ### Download events and sub-results creation ### | ||||
|   var 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> | ||||
|               ` | ||||
|  | ||||
|   // create results on click from all match ids | ||||
|   resultsCreateElement.onclick = () => { | ||||
|     resultsCreateElement.getElementsByTagName("i")[0].classList.add("hide"); | ||||
|     resultsCreateElement.innerText = "Creating..."; | ||||
|     resultsCreateElement.insertAdjacentHTML("afterbegin", loadingSpinnerHTML); | ||||
|     results.data.createResultsData("results"); | ||||
|   } | ||||
|  | ||||
|   // Add onclick to open download modal when Export Results button is pressed | ||||
|   resultsExportElement.onclick = () => { | ||||
|     exportModal.open(); | ||||
|     // add onclick to download JSON button and download the file | ||||
|     downloadResultsJSONElement = document.getElementById("download-results-json") | ||||
|     downloadResultsJSONElement.onclick = () => { | ||||
|       let filename = results.resultsData.createDownloadFilename("matches-results"); | ||||
|       results.resultsData.addData(results.metaData); | ||||
|       results.resultsData.downloadJSONRessource(filename, results.resultsData, | ||||
|                                          downloadResultsJSONElement | ||||
|       )}; | ||||
|   } | ||||
|  | ||||
|   // create sub results on click from shown marked match ids | ||||
|   subResultsCreateElement.onclick = () => { | ||||
|     subResultsCreateElement.getElementsByTagName("i")[0].remove(); | ||||
|     subResultsCreateElement.innerText = "Creating..."; | ||||
|     subResultsCreateElement.insertAdjacentHTML("afterbegin", loadingSpinnerHTML); | ||||
|     results.data.createResultsData("sub-results"); | ||||
|   } | ||||
|  | ||||
|   // Add onclick to open download modal when sub-results button is pressed | ||||
|   subResultsExportElement.onclick = () => { | ||||
|     exportModal.open(); | ||||
|     console.log(results.subResultsData); | ||||
|     // add onclick to download JSON button and download the file | ||||
|     downloadResultsJSONElement = document.getElementById("download-results-json") | ||||
|     downloadResultsJSONElement.onclick = () => { | ||||
|       let filename = results.subResultsData.createDownloadFilename("matches-sub-results"); | ||||
|       results.subResultsData.downloadJSONRessource(filename, | ||||
|                                                    results.subResultsData, | ||||
|                                                    downloadResultsJSONElement | ||||
|       )}; | ||||
|   } | ||||
|  | ||||
|   // add onclick to download JSON button and download the file | ||||
|   downloadInspectContextElement = document.getElementById("inspect-download-context") | ||||
|   downloadInspectContextElement.onclick = () => { | ||||
|     let filename = results.data.createDownloadFilename(`context-id-${results.jsList.contextId}`); | ||||
|     results.data.addData(results.metaData); | ||||
|     results.data.downloadJSONRessource(filename, | ||||
|                                        results.jsList.contextData, | ||||
|                                        downloadInspectContextElement); | ||||
|   }; | ||||
|  | ||||
|   // scroll to top button if user scrolled down the list | ||||
|   let headline = document.querySelector(".headline"); | ||||
|   let scrollToTop = document.querySelector("#menu-scroll-to-top-div"); | ||||
|   window.addEventListener("scroll", (event) => { | ||||
|     if (pageYOffset > 250) { | ||||
|       scrollToTop.classList.toggle("hide", false); | ||||
|     } else { | ||||
|       scrollToTop.classList.toggle("hide", true); | ||||
|     } | ||||
|   }); | ||||
|   scrollToTop.onclick = () => { | ||||
|     headline.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"}); | ||||
|   }; | ||||
|  | ||||
| </script> | ||||
| {% endblock %} | ||||
| @@ -1,237 +0,0 @@ | ||||
| {% extends "nopaque.html.j2" %} | ||||
|  | ||||
| {% set headline = ' ' %} | ||||
|  | ||||
| {% set full_width = True %} | ||||
| {% set imported = False %} | ||||
|  | ||||
| {% block page_content %} | ||||
| <div class="col s12"> | ||||
|   <div class="card"> | ||||
|     <div class="card-content" style="padding-top: 5px; | ||||
|                              padding-bottom: 0px;"> | ||||
|       <!-- Query form --> | ||||
|       <div class="row"> | ||||
|       <form id="query-form"> | ||||
|           <div class="col s12 m10"> | ||||
|             <div class="input-field"> | ||||
|               <i class="material-icons prefix">search</i> | ||||
|               {{ query_form.query() }} | ||||
|               {{ query_form.query.label }} | ||||
|               <span class="helper-text"> | ||||
|                 <a href="http://cwb.sourceforge.net/files/CQP_Tutorial/"> | ||||
|                   <i class="material-icons" style="font-size: inherit;">help | ||||
|                   </i> | ||||
|                   CQP query language tutorial | ||||
|                 </a> | ||||
|               </span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col s12 m2 right-align"> | ||||
|             <br class="hide-on-small-only"> | ||||
|             {{ M.render_field(query_form.submit, material_icon='send') }} | ||||
|           </div> | ||||
|       </form> | ||||
|     </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| <!-- entire results div/card --> | ||||
| <div class="col s12" id="query-display"> | ||||
|   <div class="card"> | ||||
|     <div class="card-content" id="result-list" style="overflow: hidden;"> | ||||
|       <div class="error-container hide show-on-error"></div> | ||||
|       <div class=" row hide show-on-success"> | ||||
|         {% include 'interactions/infos.html.j2' %} | ||||
|         {% include 'interactions/export.html.j2' %} | ||||
|         {% include 'interactions/create.html.j2' %} | ||||
|         {% include 'interactions/display.html.j2' %} | ||||
|         {% include 'interactions/analysis.html.j2' %} | ||||
|         {% include 'interactions/cite.html.j2' %} | ||||
|       </div> | ||||
|       {% include 'tables/query_results.html.j2' %} | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|  | ||||
| <!-- Scroll to top element --> | ||||
| {% include 'interactions/scroll_to_top.html.j2' %} | ||||
|  | ||||
| <!-- Modals --> | ||||
| {% include 'modals/show_metadata.html.j2' %} | ||||
| {% include 'modals/show_text_details.html.j2' %} | ||||
| {% include 'modals/analysis_init.html.j2' %} | ||||
| {% include 'modals/export_query_results.html.j2' %} | ||||
| {% include 'modals/context_modal.html.j2' %} | ||||
|  | ||||
| <!-- import modules --> | ||||
| <script type="module"> | ||||
| /** | ||||
|  * First Phase: | ||||
|  * Document content is loaded and scripts are being imported and executed. | ||||
|  */ | ||||
| import { | ||||
|   CorpusAnalysisClient, | ||||
|   CorpusAnalysisDisplay, | ||||
|   SocketEventListener, | ||||
|   ListenerCallback, | ||||
| } from '../../static/js/modules/nopaque.CorpusAnalysisClient.js'; | ||||
| import { | ||||
|   recieveSession, | ||||
|   recieveQueryStatus, | ||||
|   recieveQueryData, | ||||
| } from '../../static/js/modules/nopaque.listenerFunctions.js'; | ||||
| import { | ||||
|   querySetup, | ||||
|   queryRenderResults, | ||||
| } from '../../static/js/modules/nopaque.listenerCallbacks.js' | ||||
| import { | ||||
|   Results, | ||||
|   Data, | ||||
|   MetaData, | ||||
| } from '../../static/js/nopaque.Results.js'; | ||||
| import { | ||||
|   ResultsList, | ||||
| } from '../../static/js/nopaque.lists.js'; | ||||
| import { | ||||
|   scrollToTop, | ||||
| } from '../../static/js/modules/nopaque.scrollToTop.js'; | ||||
| import { | ||||
|   InteractionElement, | ||||
|   InteractionElements, | ||||
| } from '../../static/js/modules/nopaque.InteractionElement.js'; | ||||
|  | ||||
| /** | ||||
|  * Second Phase: | ||||
|  * Asynchronus and event driven code | ||||
|  */ | ||||
| document.addEventListener("DOMContentLoaded", () => { | ||||
|   // Initialize the CorpusAnalysisClient dynamic mode | ||||
|   let corpusId = {{ corpus_id}} | ||||
|   const client = new CorpusAnalysisClient({'corpusId': corpusId, | ||||
|                                            'socket': nopaque.socket, | ||||
|                                            'logging': true, | ||||
|                                            'dynamicMode': true}); | ||||
|   console.info("CorpusAnalysisClient created as client:", client); | ||||
|   // Initialize modals which are shown depending on events or client status | ||||
|   const initLoadingElement = document.getElementById("init-display"); | ||||
|   const initLoadingModal = M.Modal.init(initLoadingElement, | ||||
|                                         {"dismissible": false}); | ||||
|   // Set up display elements which are shown depending on the client status | ||||
|   const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal); | ||||
|   client.getHTMLElements(['#query-display']); | ||||
|   const queryDisplay = new CorpusAnalysisDisplay(client.queryDisplay); | ||||
|   // Register those display elements to client | ||||
|   client.setDisplay("init", initLoadingDisplay); | ||||
|   client.setDisplay("query", queryDisplay); | ||||
|   /** | ||||
|    * Initializing the results object holding all the data of a query. | ||||
|    * Also holds the metadata of one query. | ||||
|    * Lastly it contains the object ResultsList which is a list.js | ||||
|    * subclass which handles the visual representation of the query data. | ||||
|    */ | ||||
|   let displayOptionsData = ResultsList.getDisplayOptions('display-options-form'); | ||||
|   ResultsList.options.page = displayOptionsData["resultsPerPage"]; | ||||
|   let data = new Data(); | ||||
|   let resultsList = new ResultsList("result-list", ResultsList.options); | ||||
|   let resultsMetaData = new MetaData(); | ||||
|   let results = new Results(data, resultsList, resultsMetaData); | ||||
|   // Make results part of the client | ||||
|   client.results = results; | ||||
|   console.info('Initialized the Results object.') | ||||
|   /** | ||||
|    * Initialization of interactionElemnts | ||||
|    * An interactionElement is an object identifing a switch or button via | ||||
|    * htmlID. Callbacks are set for these elements which will be triggered on | ||||
|    * a pagination interaction by the user or if the status of the element has | ||||
|    * been altered. (Like the switche has ben turned on or off). | ||||
|    */ | ||||
|   let interactionElements = new InteractionElements(); | ||||
|   const expertModeInteraction = new InteractionElement("display-options-form-expert_mode"); | ||||
|   expertModeInteraction.setCallback('on', | ||||
|                                   results.jsList.expertModeOn, | ||||
|                                   results.jsList, | ||||
|                                   ['query-display', client]); | ||||
|   expertModeInteraction.setCallback('off', | ||||
|                                     results.jsList.expertModeOff, | ||||
|                                     results.jsList, | ||||
|                                     ['query-display', client]); | ||||
|   const subResultsInteraction = new InteractionElement("add-to-sub-results"); | ||||
|   subResultsInteraction.setCallback('on', | ||||
|                                      results.jsList.activateAddToSubResults, | ||||
|                                      results.jsList); | ||||
|   subResultsInteraction.setCallback('off', | ||||
|                                      results.jsList.deactivateAddToSubResults, | ||||
|                                      results.jsList); | ||||
|  | ||||
|   const activateInspectInteraction = new InteractionElement('inspect', | ||||
|                                                             false); | ||||
|   activateInspectInteraction.setCallback('noCheck', | ||||
|                                          results.jsList.activateInspect, | ||||
|                                          results.jsList); | ||||
|   const changeContextInteraction = new InteractionElement('display-options-form-results_per_page', | ||||
|                                                           false); | ||||
|   changeContextInteraction.setCallback('noCheck', | ||||
|                                        results.jsList.changeContext, | ||||
|                                        results.jsList) | ||||
|   interactionElements.addInteractions([expertModeInteraction, | ||||
|                                        subResultsInteraction, | ||||
|                                        activateInspectInteraction, | ||||
|                                        changeContextInteraction]); | ||||
|  | ||||
|   /** | ||||
|   * Checks if a change for every interactionElement happens and executes | ||||
|   * the callbacks accordingly. | ||||
|   */ | ||||
|   interactionElements.onChangeExecute(); | ||||
|   /** | ||||
|    * Register listeners listening to socket.io events and their callbacks | ||||
|    * Afterwards load them. | ||||
|    */ | ||||
|   const listenForSession = new SocketEventListener('corpus_analysis_init', | ||||
|                                                   recieveSession); | ||||
|   const listenForQueryStatus = new SocketEventListener('corpus_analysis_query', | ||||
|                                                        recieveQueryStatus); | ||||
|   const queryStatusCallback = new ListenerCallback('corpus_analysis_query', | ||||
|                                                    querySetup); | ||||
|   listenForQueryStatus.setCallbacks([queryStatusCallback]); | ||||
|   const listenForQueryData = new SocketEventListener('corpus_analysis_query_results', | ||||
|                                                   recieveQueryData); | ||||
|   const queryDataCallback = new ListenerCallback('corpus_analysis_query_results', | ||||
|                                                  queryRenderResults); | ||||
|   listenForQueryData.setCallbacks([queryDataCallback]); | ||||
|   client.setSocketEventListeners([listenForSession, listenForQueryStatus, | ||||
|                                   listenForQueryData]); | ||||
|   client.loadSocketEventListeners(); | ||||
|   // Session initialization | ||||
|   client.requestSession(); | ||||
|   // Send a query and recieve its answer data | ||||
|   let queryFormElement = document.getElementById("query-form"); | ||||
|   queryFormElement.addEventListener("submit", (event) => { | ||||
|     try { | ||||
|       /** | ||||
|        * Selects first page of result list if pagination is already available | ||||
|        * from an query submitted before. | ||||
|        * This avoids confusion for the user e.g.: The user was on page 24 | ||||
|        * reviewing the results and issues a new query. He would not see any | ||||
|        * results until the new results reach page 24 or he clicks on another | ||||
|        * valid result page element from the new pagination. | ||||
|        */ | ||||
|       let firstPageElement = document.querySelector('a.page'); | ||||
|       firstPageElement.click(); | ||||
|     } catch (e) { | ||||
|       // No page element is present if first query is submitted. | ||||
|     } | ||||
|     // Prevent page from reloading on submit | ||||
|     event.preventDefault(); | ||||
|     // Get query string and send query to server | ||||
|     results.data.getQueryStr(queryFormElement); | ||||
|     client.requestQueryData(results.data.query); | ||||
|  | ||||
|     // Add scrollToTop functionality | ||||
|     scrollToTop(); | ||||
|   }); | ||||
| }); | ||||
| </script> | ||||
| {% endblock %} | ||||
		Reference in New Issue
	
	Block a user