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