mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-10-31 10:42:43 +00:00 
			
		
		
		
	Push before rework part 2
This commit is contained in:
		| @@ -1,8 +1,10 @@ | ||||
| /** | ||||
|  * This class is used to create an CorpusAnalysisClient object. | ||||
|  * This class is used to create a CorpusAnalysisClient object. | ||||
|  * The client handels the client server communication. | ||||
|  * It requests data (e.g. the analysis session or query results) from the | ||||
|  * the server and recieves them. | ||||
|  * the server and recieves them, if it dynamicMode is true. | ||||
|  * If dynamicMode is false, the client can also handle data that is already | ||||
|  * loaded and not coming in in chunks. | ||||
|  */ | ||||
| class CorpusAnalysisClient { | ||||
|   constructor({corpusId = null, | ||||
| @@ -19,11 +21,9 @@ class CorpusAnalysisClient { | ||||
|     this.socketEventListeners = {}; | ||||
|  | ||||
|     /** | ||||
|      * Set client into imported mode if SOME THIGN IS INDICATING it | ||||
|      * | ||||
|      * Disable all console logging. | ||||
|      * Credits to https://gist.github.com/kmonsoor/0244fdb4ad79a4826371e58a1a5fa984 | ||||
|      */ | ||||
|  | ||||
|     // Disable all console logging. Credits to https://gist.github.com/kmonsoor/0244fdb4ad79a4826371e58a1a5fa984 | ||||
|     if (!logging) { | ||||
|       (() => { | ||||
|         let console = (window.console = window.console || {}); | ||||
| @@ -32,7 +32,7 @@ class CorpusAnalysisClient { | ||||
|           'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', | ||||
|           'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', | ||||
|           'time', 'timeEnd', 'timeStamp', 'trace', 'warn' | ||||
|         ].forEach(method => { | ||||
|         ].forEach((method) => { | ||||
|           console[method] = () => {}; | ||||
|         }); | ||||
|       })(); | ||||
| @@ -41,14 +41,18 @@ class CorpusAnalysisClient { | ||||
|  | ||||
|   // Registers one or more SocketEventListeners to the CorpusAnalysisClient. | ||||
|   setSocketEventListeners(socketEventListeners) { | ||||
|     for (let listener of socketEventListeners) { | ||||
|       this.socketEventListeners[listener.type] = listener.listenerFunction; | ||||
|     for (let socketEventListener of socketEventListeners) { | ||||
|       this.socketEventListeners[socketEventListener.type] = socketEventListener; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Loads the SocketEventListeners so they will be triggered on their assigned | ||||
|    * type strings because they double as the socket event event names. | ||||
|    */ | ||||
|   loadSocketEventListeners() { | ||||
|     for (let [type, listener] of Object.entries(this.socketEventListeners)) { | ||||
|       listener(this); | ||||
|       listener.listenerFunction(type, this); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -64,12 +68,14 @@ class CorpusAnalysisClient { | ||||
|    * string as the key. The selector will be converted to a valid JavaScript | ||||
|    * Field name i. e. #html-id-string -> this.htmlIdString | ||||
|    * The value will be the identifed element fetched with the querySelector | ||||
|    * method. MutlipleResults and atattchSomeCallback not yet implemented. | ||||
|    * method. | ||||
|    */ | ||||
|   getHTMLElements(arrayOfSelectors, multipleResults=false, atattchSomeCallback=false) { | ||||
|   // TODO: multipleResults=false, atattchSomeCallback=false ? | ||||
|   getHTMLElements(arrayOfSelectors) { | ||||
|     for (let selector of arrayOfSelectors) { | ||||
|       let element = document.querySelector(selector); | ||||
|       let cleanKey = []; | ||||
|       selector = selector.replace('_', '-'); | ||||
|       selector.match(/\w+/g).forEach((word) => { | ||||
|         let tmp = word[0].toUpperCase() + word.slice(1); | ||||
|         cleanKey.push(tmp); | ||||
| @@ -82,7 +88,8 @@ class CorpusAnalysisClient { | ||||
|  | ||||
|   /** | ||||
|    * Requests a corpus analysis session via socket.io. | ||||
|    * Opens a loading modal at the start of the request | ||||
|    * Opens a loading modal at the start of the request. | ||||
|    * Will be closed if session has been successfully recieved. | ||||
|    */ | ||||
|   requestSession() { | ||||
|     console.info('corpus_analysis_init: Client requesting session via', | ||||
| @@ -95,7 +102,7 @@ class CorpusAnalysisClient { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Sends the query string to the server. | ||||
|    * Request query data for the query string that has been sent to the server. | ||||
|    */ | ||||
|   requestQueryData(queryStr) { | ||||
|     console.info('corpus_analysis_query: Client requesting query data via', | ||||
| @@ -180,16 +187,57 @@ class CorpusAnalysisDisplay { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * This class is used to create an CorpusAnalysisDisplay object. | ||||
|  * Input is one HTMLElement that can then be hidden or shown depending on | ||||
|  * its CSS classes. | ||||
|  * This class is used to create an SocketEventListener. | ||||
|  * Input are an identifying type string, the listener function and callbacks | ||||
|  * which will be executed as part of the listener function. The identifying | ||||
|  * type string is also used as the socket event event identifier. | ||||
|  */ | ||||
| class SocketEventListener { | ||||
|   constructor(type, listenerFunction) { | ||||
|     this.listenerCallbacks = {}; | ||||
|     this.listenerFunction = listenerFunction; | ||||
|     this.type = type; | ||||
|   } | ||||
|  | ||||
|   // Registers callbacks to this SocketEventListener | ||||
|   setCallbacks(listenerCallbacks) { | ||||
|     for (let listenerCallback of listenerCallbacks) { | ||||
|       this.listenerCallbacks[listenerCallback.type] = listenerCallback; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** Shorthand to execute all registered callbacks with same args in insertion | ||||
|    * order. | ||||
|    * NOTE: | ||||
|    * Since ECMAScript 2015, objects do preserve creation order for | ||||
|    * string and Symbol keys. In JavaScript engines that comply with the | ||||
|    * ECMAScript 2015 spec, iterating over an object with only string keys will | ||||
|    * yield the keys in order of insertion. | ||||
|    * So all modern Browsers. | ||||
|    */ | ||||
|   executeCallbacks(args) { | ||||
|     for (let [type, listenerCallback] of Object.entries(this.listenerCallbacks)) { | ||||
|       listenerCallback.callbackFunction(...args); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * This class is used to create an ListenerCallback which will be registered | ||||
|  * to an SocketEventListener so the Listener cann invoke the ListenerCallback | ||||
|  * callback functions. | ||||
|  */ | ||||
| class ListenerCallback { | ||||
|   constructor(type, callbackFunction) { | ||||
|     this.callbackFunction = callbackFunction; | ||||
|     this.type = type; | ||||
|   } | ||||
| } | ||||
|  | ||||
| // export Classes from this module | ||||
| export {CorpusAnalysisClient, CorpusAnalysisDisplay, SocketEventListener}; | ||||
| export { | ||||
|   CorpusAnalysisClient, | ||||
|   CorpusAnalysisDisplay, | ||||
|   SocketEventListener, | ||||
|   ListenerCallback, | ||||
| }; | ||||
| @@ -62,3 +62,6 @@ class InteractionElements { | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // export Classes
 | ||||
| export { InteractionElement, InteractionElements }; | ||||
| @@ -1,10 +1,8 @@ | ||||
| // This callback is called on socket.on "query". | ||||
| // Does some hiding, showing disabling etc. | ||||
| /** | ||||
|  * This call back is called when the SocketEventListener 'recieveQueryStatus' | ||||
|  * has been triggered. It just gets the incoming status data of the issued | ||||
|  * This callback should be registered to the SocketEventListener 'recieveQueryStatus'. | ||||
|  * It just gets the incoming status data of the issued query | ||||
|  * and does some preperation work like hiding or showing elements and deleting | ||||
|  * the date from the last query. | ||||
|  * the data from the last query. | ||||
|  */ | ||||
| function querySetup(payload, client) { | ||||
|   // deletes old data from query issued before this new query | ||||
| @@ -12,23 +10,29 @@ function querySetup(payload, client) { | ||||
|   // load necessary HTMLElements with selectory syntax and save them as fields | ||||
|   client.getHTMLElements(['#query-progress-bar', '#query-results-user-feedback', | ||||
|                           '#recieved-match-count', '#total-match-count', | ||||
|                           '#text-lookup-count', '#text-lookup-titles']); | ||||
|                           '#text-lookup-count', '#text-lookup-titles', | ||||
|                           '#query-results-create', '#add-to-sub-results']); | ||||
|   client.requestQueryProgress = 0; | ||||
|   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%' | ||||
|   client.queryProgressBar.lastElementChild.style.width = '0%'; | ||||
|   if (client.dynamicMode) { | ||||
|     client.addToSubResults.toggleAttribute('disabled'); | ||||
|     client.queryResultsCreate.classList.toggle('disabled'); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * This callback is called when the SocketEventListener 'recieveQueryData' | ||||
|  * has been triggered. It takes the incoming chunk and renders the results in a | ||||
|  * the results.jsList. It can either handle live incoming data or imported | ||||
|  * results data. | ||||
|  * 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']) | ||||
|   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 | ||||
| @@ -59,11 +63,10 @@ function queryRenderResults(payload, client) { | ||||
|        * activate, hide or show elements if all reults have been recieved | ||||
|        * also load some new elements taht have not ben loaded before | ||||
|        */ | ||||
|       client.getHTMLElements(['#query-results-create']); | ||||
|       client.queryProgressBar.classList.toggle('hide'); | ||||
|       client.queryResultsUserFeedback.classList.toggle('hide'); | ||||
|       client.queryResultsCreate.classList.toggle('disabled'); | ||||
|     //   resultsExportElement.classList.remove("disabled"); | ||||
|       client.addToSubResults.toggleAttribute('disabled'); | ||||
|     //   addToSubResultsElement.removeAttribute("disabled"); | ||||
|     //   // inital expert mode check and sub results activation | ||||
|     //   client.results.jsList.activateInspect(); | ||||
| @@ -75,19 +78,21 @@ function queryRenderResults(payload, client) { | ||||
|     //   } | ||||
|     } | ||||
|   } else if (!client.dynamicMode) { | ||||
|     client.requestQueryProgress === 100; | ||||
|     client.queryResultsUserFeedback.classList.toggle('hide'); | ||||
|     renderResults(payload); | ||||
|     helperQueryRenderResults({'chunk': payload}, client); | ||||
|     client.queryProgressBar.classList.toggle('hide'); | ||||
|     client.queryResultsUserFeedback.classList.toggle('hide'); | ||||
|     client.results.jsList.activateInspect(); | ||||
|     if (expertModeSwitchElement.checked) { | ||||
|     if (client.displayOptionsFormExpertMode.checked) { | ||||
|       client.results.jsList.expertModeOn("query-display"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Helper function that saves result data into the client.results.data object. | ||||
|  * Also does some showing and hiding of Elements and user feedback text. | ||||
|  */ | ||||
| function helperQueryRenderResults (payload, client) { | ||||
|   // updating table on finished item creation callback via createResultRowElement | ||||
|   client.results.jsList.update(); | ||||
| @@ -111,6 +116,5 @@ function helperQueryRenderResults (payload, client) { | ||||
|   client.requestQueryProgress = payload.progress; | ||||
| } | ||||
|  | ||||
| // TODO: Add data to data objekt using its own socket on event? | ||||
|  | ||||
| export { querySetup, queryRenderResults } | ||||
| // export callbacks | ||||
| export { querySetup, queryRenderResults }; | ||||
| @@ -5,10 +5,10 @@ import { querySetup, queryRenderResults } from './nopaque.listenerCallbacks.js' | ||||
|  * Closes the loading modal that has been opend with requestSession at the | ||||
|  * start of the request. | ||||
|  */ | ||||
| function recieveSession(client) { | ||||
|   client.socket.on('corpus_analysis_init', (response) => { | ||||
| function recieveSession(type, client) { | ||||
|   client.socket.on(type, (response) => { | ||||
|     /** | ||||
|      * Check if request for session was ok. | ||||
|      * Check if request for session was OK. | ||||
|      * If OK execute callbacks and hide/show displays. | ||||
|      */ | ||||
|     console.group('recieve session') | ||||
| @@ -44,11 +44,11 @@ function recieveSession(client) { | ||||
|  * was invalid etc. | ||||
|  * Also prepares the result.jsList for the incoming data. | ||||
|  */ | ||||
| function recieveQueryStatus(client) { | ||||
|   client.socket.on('corpus_analysis_query', (response) => { | ||||
| function recieveQueryStatus(type, client) { | ||||
|   client.socket.on(type, (response) => { | ||||
|     /** | ||||
|      * Check if issued query was ok. | ||||
|      * If OK execute callbacks and hide/show displays. | ||||
|      * Check if issued query was OK. | ||||
|      * If OK execute registered callbacks and hide/show displays. | ||||
|      */ | ||||
|     console.group('corpus_analysis_query: Client recieving query process', | ||||
|                   'status via socket.on'); | ||||
| @@ -59,8 +59,8 @@ function recieveQueryStatus(client) { | ||||
|       if (client.displays.query != undefined)  { | ||||
|         client.displays.query.setVisibilityByStatus("success"); | ||||
|       } | ||||
|       // executing the callbacks | ||||
|       querySetup(response.payload, client); | ||||
|       // executing the registered callbacks | ||||
|       client.socketEventListeners[type].executeCallbacks([response.payload, client]); | ||||
|     } else { | ||||
|       let errorText = `Error ${response.payload.code} - ${response.payload.msg}`; | ||||
|       if (response.payload.code == 1281) { | ||||
| @@ -83,20 +83,22 @@ function recieveQueryStatus(client) { | ||||
| /** | ||||
|  * Recieves the query data from the request and handles it. | ||||
|  */ | ||||
| function recieveQueryData(client) { | ||||
| function recieveQueryData(type, client) { | ||||
|   console.group('corpus_analysis_query_results: Client recieving or loading', | ||||
|                 'query data.'); | ||||
|   if (client.dynamicMode) { | ||||
|     console.info('Client recieving query data via socket.on'); | ||||
|     client.socket.on('corpus_analysis_query_results', (response) => { | ||||
|     client.socket.on(type, (response) => { | ||||
|     console.info('Recieved chunk', response); | ||||
|     queryRenderResults(response.payload, client); | ||||
|     // executing the registered callbacks | ||||
|     client.socketEventListeners[type].executeCallbacks([response.payload, client]); | ||||
|     console.info('Added chunk data to results.data and rendered it with', | ||||
|                  'results.jsList'); | ||||
|     }); | ||||
|   } else { | ||||
|     console.info('Client loading imported query data from database.'); | ||||
|     queryRenderResults(client.results.data, client); | ||||
|     // executing the registered callbacks | ||||
|     client.socketEventListeners[type].executeCallbacks([client.results.data, client]); | ||||
|   } | ||||
|   console.groupEnd(); | ||||
| } | ||||
|   | ||||
							
								
								
									
										21
									
								
								web/app/static/js/modules/nopaque.scrollToTop.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								web/app/static/js/modules/nopaque.scrollToTop.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| /** | ||||
|  * Function to show a scrol lto top button if the user has scrolled down | ||||
|  * 250 pixels from teh headline element. | ||||
|  */ | ||||
| function scrollToTop() { | ||||
|   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"}); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| // export function | ||||
| export { scrollToTop }; | ||||
| @@ -425,6 +425,10 @@ RessourceList.options = { | ||||
|  | ||||
|  | ||||
| class ResultsList extends List { | ||||
|   /** | ||||
|    * If no options are given when a new instance of this class is created | ||||
|    * the options below are used. | ||||
|    */ | ||||
|   static options = { | ||||
|     page: 10, | ||||
|     pagination: [{ | ||||
| @@ -443,12 +447,19 @@ class ResultsList extends List { | ||||
|   constructor(idOrElement, options) { | ||||
|     super(idOrElement, options); | ||||
|     this.options = options; | ||||
|     this.eventTokens = {};  // all span tokens which are holdeing events if expert | ||||
|     // mode is on. Collected here to delete later on | ||||
|     this.currentExpertTokenElements = {}; // all token elements which have added | ||||
|     // classes like chip and hoverable for expert view. Collected | ||||
|     //here to delete later on | ||||
|     this.addToSubResultsStatus = {};  // 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. | ||||
|     /** | ||||
|      * All span tokens which are holding events if expert | ||||
|      * mode is on. Collected here to delete later on. | ||||
|      */ | ||||
|     this.eventTokens = {}; | ||||
|     /** | ||||
|     * all token elements which have added | ||||
|     * classes like chip and hoverable for expert view. Collected | ||||
|     * here to delete later on | ||||
|     */ | ||||
|     this.currentExpertTokenElements = {}; | ||||
|      // 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. | ||||
|   } | ||||
|  | ||||
| @@ -620,7 +631,7 @@ class ResultsList extends List { | ||||
|   // ###### Functions to inspect one match, to show more details ###### | ||||
|   // activate inspect buttons if progress is 100 | ||||
|   activateInspect() { | ||||
|     if (progress === 100) { | ||||
|     if (this.requestQueryProgress === 100) { | ||||
|       let inspectBtnElements; | ||||
|       inspectBtnElements = document.getElementsByClassName("inspect"); | ||||
|       for (let inspectBtn of inspectBtnElements) { | ||||
| @@ -958,45 +969,43 @@ class ResultsList extends List { | ||||
|  | ||||
|   // ###### Expert view event functions ###### | ||||
|   // function to create a tooltip for the current hovered token | ||||
|   tooltipEventCreate(event) { | ||||
|   tooltipEventCreate(event, client) { | ||||
|     // console.log("Create Tooltip on mouseover."); | ||||
|     let token; | ||||
|     token = results.data.cpos_lookup[event.target.dataset.cpos]; | ||||
|     let token = client.results.data.cpos_lookup[event.target.dataset.cpos]; | ||||
|     if (!token) { | ||||
|       token = this.contextData.cpos_lookup[event.target.dataset.cpos]; | ||||
|     } | ||||
|     this.addToolTipToTokenElement(event.target, token); | ||||
|     this.addToolTipToTokenElement(event.target, token, client); | ||||
|   } | ||||
|  | ||||
|   // Function to destroy the current Tooltip for the current hovered tooltip | ||||
|   // on mouse leave | ||||
|   tooltipEventDestroy(event) { | ||||
|   tooltipEventDestroy() { | ||||
|     // console.log("Tooltip destroy on leave."); | ||||
|     this.currentTooltipElement.destroy(); | ||||
|   } | ||||
|  | ||||
|   expertModeOn(htmlId) { | ||||
|   // turn the expert mode on for all tokens in the DOM element identified by its htmlID | ||||
|   expertModeOn(htmlId, client) { | ||||
|     if (!Array.isArray(this.currentExpertTokenElements[htmlId])) { | ||||
|       this.currentExpertTokenElements[htmlId] = []; | ||||
|     } | ||||
|     let container = document.getElementById(htmlId); | ||||
|     let tokens = container.querySelectorAll("span.token"); | ||||
|     this.currentExpertTokenElements[htmlId].push(...tokens); | ||||
|     this.tooltipEventCreateBind = this.tooltipEventCreate.bind(this); | ||||
|     this.tooltipEventDestroyBind = this.tooltipEventDestroy.bind(this); | ||||
|     this.eventTokens[htmlId] = []; | ||||
|     for (let tokenElement of this.currentExpertTokenElements[htmlId]) { | ||||
|       tokenElement.classList.add("chip", "hoverable", "expert-view"); | ||||
|       tokenElement.onmouseover = this.tooltipEventCreateBind; | ||||
|       tokenElement.onmouseout = this.tooltipEventDestroyBind; | ||||
|       const eventCreate = (event, arg) => this.tooltipEventCreate(event, arg); | ||||
|       tokenElement.onmouseover = (event) => eventCreate(event, client); | ||||
|       tokenElement.onmouseout = () => this.tooltipEventDestroy(); | ||||
|       this.eventTokens[htmlId].push(tokenElement); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // fuction that creates Tooltip for one token and extracts the corresponding | ||||
|   // infos from the result JSON | ||||
|   addToolTipToTokenElement(tokenElement, token) { | ||||
|   addToolTipToTokenElement(tokenElement, token, client) { | ||||
|     this.currentTooltipElement; | ||||
|     this.currentTooltipElement = M.Tooltip.init(tokenElement, | ||||
|      {"html": `<table> | ||||
| @@ -1013,11 +1022,11 @@ class ResultsList extends List { | ||||
|                      NER: ${token.ner} | ||||
|                    </td> | ||||
|                    <td class="left-align"> | ||||
|                      Title: ${results.data.text_lookup[token.text].title} | ||||
|                      Title: ${client.results.data.text_lookup[token.text].title} | ||||
|                      <br> | ||||
|                      Author: ${results.data.text_lookup[token.text].author} | ||||
|                      Author: ${client.results.data.text_lookup[token.text].author} | ||||
|                      <br> | ||||
|                      Publishing year: ${results.data.text_lookup[token.text].publishing_year} | ||||
|                      Publishing year: ${client.results.data.text_lookup[token.text].publishing_year} | ||||
|                    </td> | ||||
|                  </tr> | ||||
|                </table>`} | ||||
|   | ||||
| @@ -69,22 +69,45 @@ | ||||
| <script type="module"> | ||||
| /** | ||||
|  * 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 { CorpusAnalysisClient, | ||||
| import { | ||||
|   CorpusAnalysisClient, | ||||
|   CorpusAnalysisDisplay, | ||||
|         SocketEventListener } from '../../static/js/modules/nopaque.CorpusAnalysisClient.js'; | ||||
| import { recieveSession, recieveQueryStatus, | ||||
|         recieveQueryData } from '../../static/js/modules/nopaque.listenerFunctions.js'; | ||||
| import { Results, Data, MetaData } from '../../static/js/nopaque.Results.js'; | ||||
| import { ResultsList } from '../../static/js/nopaque.lists.js'; | ||||
|   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 | ||||
|   // Initialize the CorpusAnalysisClient dynamic mode | ||||
|   let corpusId = {{ corpus_id}} | ||||
|   const client = new CorpusAnalysisClient({'corpusId': corpusId, | ||||
|                                            'socket': nopaque.socket, | ||||
| @@ -95,7 +118,7 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
|   const initLoadingElement = document.getElementById("init-display"); | ||||
|   const initLoadingModal = M.Modal.init(initLoadingElement, | ||||
|                                         {"dismissible": false}); | ||||
|   // Set up display elements which hare show depending on the client status | ||||
|   // 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); | ||||
| @@ -105,8 +128,6 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
|   /** | ||||
|    * Initializing the results object holding all the data of a query. | ||||
|    * Also holds the metadata of one query. | ||||
|    * resultsListOptions is set to determine how many results per page are | ||||
|    * shown etc. | ||||
|    * Lastly it contains the object ResultsList which is a list.js | ||||
|    * subclass which handles the visual representation of the query data. | ||||
|    */ | ||||
| @@ -116,16 +137,70 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
|   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 | ||||
|   // Make results part of the client | ||||
|   client.results = results; | ||||
|   console.info('Initialized the Results object.') | ||||
|   // register listeners listening to socket.io events and load them | ||||
|   /** | ||||
|    * 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(); | ||||
| @@ -153,6 +228,9 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
|     // Get query string and send query to server | ||||
|     results.data.getQueryStr(queryFormElement); | ||||
|     client.requestQueryData(results.data.query); | ||||
|  | ||||
|     // Add scrollToTop functionality | ||||
|     scrollToTop(); | ||||
|   }); | ||||
| }); | ||||
| </script> | ||||
|   | ||||
| @@ -10,8 +10,7 @@ results.--> | ||||
|         Sub-Results creation: | ||||
|         <label> | ||||
|           Off | ||||
|           <input disabled | ||||
|                  type="checkbox" | ||||
|           <input type="checkbox" | ||||
|                  id="add-to-sub-results"> | ||||
|           <span class="lever"></span> | ||||
|           On | ||||
|   | ||||
| @@ -9,7 +9,6 @@ the selected sub results.--> | ||||
|       <button class="waves-effect | ||||
|               waves-light | ||||
|               btn-flat | ||||
|               disabled | ||||
|               flat-interaction" | ||||
|               type="submit" | ||||
|               id="query-results-create">Create Results | ||||
| @@ -30,7 +29,6 @@ the selected sub results.--> | ||||
|               waves-light | ||||
|               btn-flat | ||||
|               hide | ||||
|               disabled | ||||
|               flat-interaction" | ||||
|               type="submit" | ||||
|               id="sub-results-create">Create Sub-Results | ||||
|   | ||||
| @@ -59,21 +59,39 @@ | ||||
|  * First Phase: | ||||
|  * document content is loaded and scripts are being imported and executed | ||||
|  */ | ||||
| import { CorpusAnalysisClient, | ||||
|  import { | ||||
|    CorpusAnalysisClient, | ||||
|    CorpusAnalysisDisplay, | ||||
|         SocketEventListener } from '../../static/js/modules/nopaque.CorpusAnalysisClient.js'; | ||||
| import { recieveSession, recieveQueryStatus, | ||||
|         recieveQueryData } from '../../static/js/modules/nopaque.listenerFunctions.js'; | ||||
| import { Results, Data, MetaData } from '../../static/js/nopaque.Results.js'; | ||||
| import { ResultsList } from '../../static/js/nopaque.lists.js'; | ||||
| import { queryRenderResults, querySetup } from '../../static/js/modules/nopaque.listenerCallbacks.js' | ||||
|    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'; | ||||
|  | ||||
| /** | ||||
|  * Second Phase: | ||||
|  * Asynchronus and event driven code | ||||
|  */ | ||||
| document.addEventListener("DOMContentLoaded", () => { | ||||
|   // Initialize the CorpusAnalysisClient | ||||
|   // Initialize the CorpusAnalysisClient with dynamicMode as false | ||||
|   const client = new CorpusAnalysisClient({'logging': true, | ||||
|                                            'dynamicMode': false}); | ||||
|   console.info("CorpusAnalysisClient created as client:", client); | ||||
| @@ -85,8 +103,6 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
|   /** | ||||
|    * Initializing the results object holding all the data of a query. | ||||
|    * Also holds the metadata of one query. | ||||
|    * resultsListOptions is set to determine how many results per page are | ||||
|    * shown etc. | ||||
|    * Lastly it contains the object ResultsList which is a list.js | ||||
|    * subclass which handles the visual representation of the query data. | ||||
|    */ | ||||
| @@ -114,7 +130,22 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
|                                  'onOpenEnd': deleteOverlay}); | ||||
|   // saving imported data into client object | ||||
|   const payload = {{ query_result_file_content|tojson|safe }}; | ||||
|  | ||||
|   /** | ||||
|    * Register listeners and their callbacks. Because we are using the client | ||||
|    * not in dynamic mode we will not load the listeners. We just call the | ||||
|    * callbacks of the listeners manually. This is done to keep the setup of | ||||
|    * the client in dynamic or not dynamic mode similarish. | ||||
|    */ | ||||
|    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]); | ||||
|  | ||||
| // | ||||
| //   // Initialization of interactionElemnts | ||||
| @@ -160,9 +191,8 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
| //   } | ||||
| // | ||||
|   // render results directly with callbacks because we are not in dynamic mode | ||||
|   querySetup(payload, client); | ||||
|   queryRenderResults(payload, client); | ||||
|  | ||||
|   listenForQueryStatus.listenerCallbacks['corpus_analysis_query'].callbackFunction(payload, client); | ||||
|   listenForQueryData.listenerCallbacks['corpus_analysis_query_results'].callbackFunction(payload, client); | ||||
| //   // ### Show corpus Metadata | ||||
| //   showMetaDataButton.onclick = () => { | ||||
| //     metaDataModal.open(); | ||||
| @@ -185,19 +215,8 @@ document.addEventListener("DOMContentLoaded", () => { | ||||
| //     } | ||||
| //   }); | ||||
| // | ||||
| //   // 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"}); | ||||
| //   }; | ||||
|   // Add scrollToTop functionality | ||||
|   scrollToTop(); | ||||
| }); | ||||
| </script> | ||||
| {% endblock %} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user