mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 12:22:47 +00:00 
			
		
		
		
	Further rework
This commit is contained in:
		@@ -5,12 +5,38 @@
 | 
			
		||||
 * the server and recieves them.
 | 
			
		||||
 */
 | 
			
		||||
class CorpusAnalysisClient {
 | 
			
		||||
  constructor(corpusId, socket, logging=false) {
 | 
			
		||||
  constructor({corpusId = null,
 | 
			
		||||
               socket = null,
 | 
			
		||||
               logging = true,
 | 
			
		||||
               dynamicMode = true} = {}) {
 | 
			
		||||
    this.corpusId = corpusId;
 | 
			
		||||
    this.displays = {};
 | 
			
		||||
    this.dynamicMode = dynamicMode;
 | 
			
		||||
    this.logging = logging;
 | 
			
		||||
    this.requestQueryProgress = 0;
 | 
			
		||||
    this.results = undefined;  // holds the results object later on
 | 
			
		||||
    this.socket = socket;
 | 
			
		||||
    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
 | 
			
		||||
    if (!logging) {
 | 
			
		||||
      (() => {
 | 
			
		||||
        let console = (window.console = window.console || {});
 | 
			
		||||
        [
 | 
			
		||||
          'assert', 'clear', 'count', 'debug', 'dir', 'dirxml',
 | 
			
		||||
          'error', 'exception', 'group', 'groupCollapsed', 'groupEnd',
 | 
			
		||||
          'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table',
 | 
			
		||||
          'time', 'timeEnd', 'timeStamp', 'trace', 'warn'
 | 
			
		||||
        ].forEach(method => {
 | 
			
		||||
          console[method] = () => {};
 | 
			
		||||
        });
 | 
			
		||||
      })();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Registers one or more SocketEventListeners to the CorpusAnalysisClient.
 | 
			
		||||
@@ -31,10 +57,32 @@ class CorpusAnalysisClient {
 | 
			
		||||
    this.displays[type] = corpusAnalysisDisplay;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Function that takes one or more query selector
 | 
			
		||||
   * strings in an array as an input. The function then creates a
 | 
			
		||||
   * class field in the client object with the query selector
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  getHTMLElements(arrayOfSelectors, multipleResults=false, atattchSomeCallback=false) {
 | 
			
		||||
    for (let selector of arrayOfSelectors) {
 | 
			
		||||
      let element = document.querySelector(selector);
 | 
			
		||||
      let cleanKey = [];
 | 
			
		||||
      selector.match(/\w+/g).forEach((word) => {
 | 
			
		||||
        let tmp = word[0].toUpperCase() + word.slice(1);
 | 
			
		||||
        cleanKey.push(tmp);
 | 
			
		||||
      });
 | 
			
		||||
      cleanKey[0] = cleanKey[0].toLowerCase();
 | 
			
		||||
      cleanKey = cleanKey.join('');
 | 
			
		||||
      this[cleanKey] = element;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Requests a corpus analysis session via socket.io.
 | 
			
		||||
   * Opens a loading modal at the start of the request
 | 
			
		||||
   * Should be a private method if ES2020 is finalized (Maybe?)
 | 
			
		||||
   */
 | 
			
		||||
  requestSession() {
 | 
			
		||||
    console.info('corpus_analysis_init: Client requesting session via',
 | 
			
		||||
@@ -48,12 +96,11 @@ class CorpusAnalysisClient {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sends the query string to the server.
 | 
			
		||||
   * Should be a private method if ES2020 is finalized (Maybe?)
 | 
			
		||||
   */
 | 
			
		||||
  requestQueryData(queryStr) {
 | 
			
		||||
    console.info('corpus_analysis_query: Client requesting query data via',
 | 
			
		||||
                 'socket.emit for the query', queryStr);
 | 
			
		||||
    // TODO: Display stuff
 | 
			
		||||
    // TODO: Display stuff ?
 | 
			
		||||
    this.socket.emit('corpus_analysis_query', queryStr);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,37 +1,68 @@
 | 
			
		||||
// 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
 | 
			
		||||
 * and does some preperation work like hiding or showing elements and deleting
 | 
			
		||||
 * the date from the last query.
 | 
			
		||||
 */
 | 
			
		||||
function querySetup(payload, client) {
 | 
			
		||||
  // deletes old data from query issued before this new query
 | 
			
		||||
  client.results.clearAll();
 | 
			
		||||
  // 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']);
 | 
			
		||||
  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%'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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 eiterh hande llive incoming data or imported
 | 
			
		||||
 * the results.jsList. It can either handle live incoming data or imported
 | 
			
		||||
 * results data.
 | 
			
		||||
 */
 | 
			
		||||
function queryRenderResults(payload, client, imported=false) {
 | 
			
		||||
  console.info("Current recieved chunk:", payload.chunk);
 | 
			
		||||
  if (payload.chunk.cpos_ranges == true) {
 | 
			
		||||
    client.results.data["cpos_ranges"] = true;
 | 
			
		||||
  } else {
 | 
			
		||||
    client.results.data["cpos_ranges"] = false;
 | 
			
		||||
function queryRenderResults(payload, client) {
 | 
			
		||||
  client.getHTMLElements(['#recieved-match-count', '#match-count'])
 | 
			
		||||
  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);
 | 
			
		||||
       }
 | 
			
		||||
     });
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * resultItem is a list where
 | 
			
		||||
   */
 | 
			
		||||
  let resultItems = [];
 | 
			
		||||
  // get infos for full match row
 | 
			
		||||
  for (let [index, match] of payload.chunk.matches.entries()) {
 | 
			
		||||
    resultItems.push({...match, ...{"index": index + client.results.data.matches.length}});
 | 
			
		||||
  }
 | 
			
		||||
  if (!imported) {
 | 
			
		||||
    // update progress bar
 | 
			
		||||
    // queryResultsDeterminateElement.style.width = `${payload.progress}%`;
 | 
			
		||||
    client.results.jsList.add(resultItems, (items) => {
 | 
			
		||||
      for (let item of items) {
 | 
			
		||||
        item.elm = client.results.jsList.createResultRowElement(item, payload.chunk);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  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);
 | 
			
		||||
    // if (progress === 100) {
 | 
			
		||||
    //   resultsCreateElement.classList.remove("disabled");
 | 
			
		||||
    //   queryResultsProgressElement.classList.add("hide");
 | 
			
		||||
    //   queryResultsUserFeedbackElement.classList.add("hide");
 | 
			
		||||
    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.getHTMLElements(['#query-results-create']);
 | 
			
		||||
      client.queryProgressBar.classList.toggle('hide');
 | 
			
		||||
      client.queryResultsUserFeedback.classList.toggle('hide');
 | 
			
		||||
      client.queryResultsCreate.classList.toggle('disabled');
 | 
			
		||||
    //   resultsExportElement.classList.remove("disabled");
 | 
			
		||||
    //   addToSubResultsElement.removeAttribute("disabled");
 | 
			
		||||
    //   // inital expert mode check and sub results activation
 | 
			
		||||
@@ -42,20 +73,18 @@ function queryRenderResults(payload, client, imported=false) {
 | 
			
		||||
    //   if (expertModeSwitchElement.checked) {
 | 
			
		||||
    //     client.results.jsList.expertModeOn("query-display");
 | 
			
		||||
    //   }
 | 
			
		||||
    // }
 | 
			
		||||
  } else if (imported) {
 | 
			
		||||
    client.results.jsList.add(resultItems, (items) => {
 | 
			
		||||
      for (let item of items) {
 | 
			
		||||
        item.elm = client.results.jsList.createResultRowElement(item, payload.chunk,
 | 
			
		||||
                                                         true);
 | 
			
		||||
      }
 | 
			
		||||
      helperQueryRenderResults(payload, client);
 | 
			
		||||
      progress = 100;
 | 
			
		||||
      client.results.jsList.activateInspect();
 | 
			
		||||
      if (expertModeSwitchElement.checked) {
 | 
			
		||||
        client.results.jsList.expertModeOn("query-display");
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    }
 | 
			
		||||
  } 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) {
 | 
			
		||||
      client.results.jsList.expertModeOn("query-display");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -65,20 +94,23 @@ function helperQueryRenderResults (payload, client) {
 | 
			
		||||
  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");
 | 
			
		||||
  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
 | 
			
		||||
  // receivedMatchCountElement.innerText = `${client.results.data.matches.length}`;
 | 
			
		||||
  // textLookupCountElement.innerText = `${Object.keys(client.results.data.text_lookup).length}`;
 | 
			
		||||
  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})`);
 | 
			
		||||
  };
 | 
			
		||||
  // textTitlesElement.innerText = `${titles.join(", ")}`;
 | 
			
		||||
  // upate progress status
 | 
			
		||||
  // progress = payload.progress;  // global declaration
 | 
			
		||||
  client.textLookupTitles.textContent = `${titles.join(", ")}`;
 | 
			
		||||
  // update progress bar and requestQueryProgress
 | 
			
		||||
  client.queryProgressBar.lastElementChild.style.width =  `${payload.progress}%`;
 | 
			
		||||
  client.requestQueryProgress = payload.progress;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { queryRenderResults }
 | 
			
		||||
// TODO: Add data to data objekt using its own socket on event?
 | 
			
		||||
 | 
			
		||||
export { querySetup, queryRenderResults }
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import {queryRenderResults} from './nopaque.listenerCallbacks.js'
 | 
			
		||||
import { querySetup, queryRenderResults } from './nopaque.listenerCallbacks.js'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Recieves a corpus analysis session via socket.io.
 | 
			
		||||
@@ -7,13 +7,18 @@ import {queryRenderResults} from './nopaque.listenerCallbacks.js'
 | 
			
		||||
 */
 | 
			
		||||
function recieveSession(client) {
 | 
			
		||||
  client.socket.on('corpus_analysis_init', (response) => {
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if request for session was ok.
 | 
			
		||||
     * If OK execute callbacks and hide/show displays.
 | 
			
		||||
     */
 | 
			
		||||
    console.group('recieve session')
 | 
			
		||||
    console.info('corpus_analysis_init: Client recieving session/or error',
 | 
			
		||||
                 'codes via socket.on');
 | 
			
		||||
    if (response.code === 200) {
 | 
			
		||||
      console.info('corpus_analysis_init: Client recieving session/or error',
 | 
			
		||||
                   'codes via socket.on');
 | 
			
		||||
      console.info(`corpus_analysis_init: ${response.code} - ${response.msg}`);
 | 
			
		||||
      console.info('corpus_analysis_init: Initialization succeeded');
 | 
			
		||||
      console.info(response);
 | 
			
		||||
      console.groupEnd();
 | 
			
		||||
      // Handling hide/show of displays
 | 
			
		||||
      if (client.displays.init != undefined) {
 | 
			
		||||
        client.displays.init.element.M_Modal.close();
 | 
			
		||||
        client.displays.init.setVisibilityByStatus('success');
 | 
			
		||||
@@ -29,6 +34,7 @@ function recieveSession(client) {
 | 
			
		||||
      }
 | 
			
		||||
      console.error(`corpus_analysis_init: ${errorText}`);
 | 
			
		||||
    }
 | 
			
		||||
    console.groupEnd();
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -40,10 +46,36 @@ function recieveSession(client) {
 | 
			
		||||
 */
 | 
			
		||||
function recieveQueryStatus(client) {
 | 
			
		||||
  client.socket.on('corpus_analysis_query', (response) => {
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if issued query was ok.
 | 
			
		||||
     * If OK execute callbacks and hide/show displays.
 | 
			
		||||
     */
 | 
			
		||||
    console.group('corpus_analysis_query: Client recieving query process',
 | 
			
		||||
                 'status via socket.on');
 | 
			
		||||
    client.results.clearAll();
 | 
			
		||||
    console.info(response);
 | 
			
		||||
                  'status via socket.on');
 | 
			
		||||
    if (response.code === 200) {
 | 
			
		||||
      console.info(`corpus_analysis_query: ${response.code} - ${response.msg}`);
 | 
			
		||||
      console.info(response);
 | 
			
		||||
      // Handling hide/show of displays
 | 
			
		||||
      if (client.displays.query != undefined)  {
 | 
			
		||||
        client.displays.query.setVisibilityByStatus("success");
 | 
			
		||||
      }
 | 
			
		||||
      // executing the callbacks
 | 
			
		||||
      querySetup(response.payload, client);
 | 
			
		||||
    } else {
 | 
			
		||||
      let errorText = `Error ${response.payload.code} - ${response.payload.msg}`;
 | 
			
		||||
      if (response.payload.code == 1281) {
 | 
			
		||||
        errorText += ' - Invalid Query';
 | 
			
		||||
      }
 | 
			
		||||
      nopaque.flash(errorText, "error");
 | 
			
		||||
      if (client.displays.query.errorContainer != undefined)  {
 | 
			
		||||
        client.displays.query.errorContainer.innerHTML = `<p class="red-text">`+
 | 
			
		||||
                  `<i class="material-icons tiny">error</i> ${errorText}</p>`;
 | 
			
		||||
      }
 | 
			
		||||
      if (client.displays.query != undefined)  {
 | 
			
		||||
        client.displays.query.setVisibilityByStatus("error");
 | 
			
		||||
      }
 | 
			
		||||
      console.error(`corpus_analysis_query: ${errorText}`);
 | 
			
		||||
    }
 | 
			
		||||
    console.groupEnd();
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
@@ -52,15 +84,21 @@ function recieveQueryStatus(client) {
 | 
			
		||||
 * Recieves the query data from the request and handles it.
 | 
			
		||||
 */
 | 
			
		||||
function recieveQueryData(client) {
 | 
			
		||||
  client.socket.on('corpus_analysis_query_results', (response) => {
 | 
			
		||||
    console.group('corpus_analysis_query_results: Client recieving query',
 | 
			
		||||
                  'data via socket.on');
 | 
			
		||||
  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) => {
 | 
			
		||||
    console.info('Recieved chunk', response);
 | 
			
		||||
    queryRenderResults(response.payload, client);
 | 
			
		||||
    console.info('Added chunk data to results.data and rendered it with',
 | 
			
		||||
                 'results.jsList')
 | 
			
		||||
    console.groupEnd();
 | 
			
		||||
  });
 | 
			
		||||
                 'results.jsList');
 | 
			
		||||
    });
 | 
			
		||||
  } else {
 | 
			
		||||
    console.info('Client loading imported query data from database.');
 | 
			
		||||
    queryRenderResults(client.results.data, client);
 | 
			
		||||
  }
 | 
			
		||||
  console.groupEnd();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// export listeners from this module
 | 
			
		||||
 
 | 
			
		||||
@@ -23,12 +23,12 @@ class Data {
 | 
			
		||||
  // Sets empty object structure. Also usefull to delete old results.
 | 
			
		||||
  // matchCount default is 0
 | 
			
		||||
  init(matchCount = 0, type = "results") {
 | 
			
		||||
    this["matches"] = [];  // list of all c with lc and rc
 | 
			
		||||
    this["cpos_lookup"] = {};  // object contains all this key value pair
 | 
			
		||||
    this["text_lookup"] = {};  // same as above for all text ids
 | 
			
		||||
    this["match_count"] = matchCount;
 | 
			
		||||
    this["corpus_type"] = "results";
 | 
			
		||||
    this["query"] = "";
 | 
			
		||||
    this.matches = [];  // list of all c with lc and rc
 | 
			
		||||
    this.cpos_lookup = {};  // object contains all this key value pair
 | 
			
		||||
    this.text_lookup = {};  // same as above for all text ids
 | 
			
		||||
    this.match_count = matchCount;
 | 
			
		||||
    this.corpus_type = 'results';
 | 
			
		||||
    this.query = '';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  addData(jsonData, key=null) {
 | 
			
		||||
@@ -45,7 +45,7 @@ class Data {
 | 
			
		||||
    let queryFormData;
 | 
			
		||||
    let queryStr;
 | 
			
		||||
    queryFormData = new FormData(queryFormElement);
 | 
			
		||||
    queryStr = queryFormData.get("query-form-query");
 | 
			
		||||
    queryStr = queryFormData.get('query-form-query');
 | 
			
		||||
    this["query"] = queryStr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +72,7 @@ class Data {
 | 
			
		||||
  // Function to download data as Blob created from string
 | 
			
		||||
  // should be private but that is not yet a feature of javascript 08.04.2020
 | 
			
		||||
  download(downloadElement, dataStr, filename, type, filenameSlug) {
 | 
			
		||||
    console.log("Start Download!");
 | 
			
		||||
    console.log('Start Download!');
 | 
			
		||||
    let file;
 | 
			
		||||
    filename += filenameSlug;
 | 
			
		||||
    file = new Blob([dataStr], {type: type});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										83
									
								
								web/app/static/js/web-components/InfoMenu.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								web/app/static/js/web-components/InfoMenu.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
/**
 | 
			
		||||
 * HTML for showing infos about the current query or result. Also gives
 | 
			
		||||
 * the user the abiltiy to access the meta data for the current query or
 | 
			
		||||
 * result.
 | 
			
		||||
 */
 | 
			
		||||
const template = document.createElement('template');
 | 
			
		||||
template.innerHTML = `
 | 
			
		||||
 | 
			
		||||
  <link rel="stylesheet" href="../../static/fonts/Material_design_icons/material-icons.css">
 | 
			
		||||
  <link rel="stylesheet" href="../../static/css/Materialize/materialize.min.css">
 | 
			
		||||
  <link rel="stylesheet" href="../../static/css/nopaque.css">
 | 
			
		||||
 | 
			
		||||
  <div class="col">
 | 
			
		||||
    <h6 style="margin-top: 0px;">Infos</h6>
 | 
			
		||||
    <div class="divider" style="margin-bottom: 10px;"></div>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col s12">
 | 
			
		||||
        <button id="show-metadata"
 | 
			
		||||
                class="waves-effect
 | 
			
		||||
                       waves-light
 | 
			
		||||
                       btn-flat
 | 
			
		||||
                       flat-interaction"
 | 
			
		||||
                type="submit">Corpus Metadata
 | 
			
		||||
          <i class="material-icons left">info_outline</i>
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col s12">
 | 
			
		||||
        <p>
 | 
			
		||||
          <slot name="received-match-count">
 | 
			
		||||
            0
 | 
			
		||||
          </slot> of
 | 
			
		||||
          <slot name="match-count">(to be determined)</slot>
 | 
			
		||||
          matches loaded.
 | 
			
		||||
          <br>
 | 
			
		||||
          Matches occured in
 | 
			
		||||
          <slot name="text-lookup-count">(to be determined)</slot>
 | 
			
		||||
          corpus files:
 | 
			
		||||
          <br>
 | 
			
		||||
          <slot name=text-titles>(to be determined)</slot>
 | 
			
		||||
        </p>
 | 
			
		||||
        <p id="query-results-user-feedback">
 | 
			
		||||
          <i class="material-icons">help</i>
 | 
			
		||||
          The Server is still sending your results.
 | 
			
		||||
          Functions like "Export Results" and "Match Inspect" will be
 | 
			
		||||
          available after all matches have been loaded.
 | 
			
		||||
        </p>
 | 
			
		||||
        <div class="progress" id="query-progress-bar">
 | 
			
		||||
          <div class="determinate"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
class InfoMenu extends HTMLElement {
 | 
			
		||||
  constructor() {
 | 
			
		||||
    super();
 | 
			
		||||
 | 
			
		||||
    this.appendChild(template.content.cloneNode(true));
 | 
			
		||||
    this.attachShadow({ mode: 'open' });
 | 
			
		||||
    this.shadowRoot.appendChild(template.content.cloneNode(true));
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // methods that will be used in connectedCallback on eventListeners
 | 
			
		||||
  showMetadata() {
 | 
			
		||||
    console.log('Show metadata somehow');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  connectedCallback() {
 | 
			
		||||
    const showMetadataBtn = this.querySelector('#show-metadata');
 | 
			
		||||
    showMetadataBtn.addEventListener('click', () => this.showMetadata());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  disconnectedCallback() {
 | 
			
		||||
    const showMetadataBtn = this.querySelector('#show-metadata');
 | 
			
		||||
    showMetadataBtn.removeEventListener();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.customElements.define('info-menu', InfoMenu);
 | 
			
		||||
 | 
			
		||||
export { InfoMenu };
 | 
			
		||||
@@ -67,89 +67,93 @@
 | 
			
		||||
 | 
			
		||||
<!-- import modules -->
 | 
			
		||||
<script type="module">
 | 
			
		||||
  /**
 | 
			
		||||
   * First Phase:
 | 
			
		||||
   * document content is loaded and scripts are being imported and executed
 | 
			
		||||
   */
 | 
			
		||||
  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';
 | 
			
		||||
/**
 | 
			
		||||
 * First Phase:
 | 
			
		||||
 * document content is loaded and scripts are being imported and executed
 | 
			
		||||
 */
 | 
			
		||||
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';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Second Phase:
 | 
			
		||||
 * Asynchronus and event driven code
 | 
			
		||||
 */
 | 
			
		||||
document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
  // Initialize the CorpusAnalysisClient
 | 
			
		||||
  let corpusId = {{ corpus_id}}
 | 
			
		||||
  const client = new CorpusAnalysisClient({'corpusId': corpusId,
 | 
			
		||||
                                           'socket': nopaque.socket,
 | 
			
		||||
                                           'logging': true,
 | 
			
		||||
                                           'dynamicMode': true});
 | 
			
		||||
  console.info("CorpusAnalysisClient created as client:", client);
 | 
			
		||||
  // Initialize modals which are shown depending on events or client status
 | 
			
		||||
  const initLoadingElement = document.getElementById("init-display");
 | 
			
		||||
  const initLoadingModal = M.Modal.init(initLoadingElement,
 | 
			
		||||
                                        {"dismissible": false});
 | 
			
		||||
  // Set up display elements which hare show depending on the client status
 | 
			
		||||
  const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal);
 | 
			
		||||
  client.getHTMLElements(['#query-display']);
 | 
			
		||||
  const queryDisplay = new CorpusAnalysisDisplay(client.queryDisplay);
 | 
			
		||||
  // Register those display elements to client
 | 
			
		||||
  client.setDisplay("init", initLoadingDisplay);
 | 
			
		||||
  client.setDisplay("query", queryDisplay);
 | 
			
		||||
  /**
 | 
			
		||||
   * Second Phase:
 | 
			
		||||
   * Asynchronus and event driven code
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
    // Initialize the CorpusAnalysisClient
 | 
			
		||||
    const client = new CorpusAnalysisClient({{ corpus_id }}, nopaque.socket);
 | 
			
		||||
    console.info("CorpusAnalysisClient created as client:", client);
 | 
			
		||||
    // Initialize modals which are shown depending on events or client status
 | 
			
		||||
    const initLoadingElement = document.getElementById("init-display");
 | 
			
		||||
    const initLoadingModal = M.Modal.init(initLoadingElement,
 | 
			
		||||
                                          {"dismissible": false});
 | 
			
		||||
    // Set up display elements which hare show depending on the client status
 | 
			
		||||
    const initLoadingDisplay = new CorpusAnalysisDisplay(initLoadingModal);
 | 
			
		||||
    // Register those display elements to client
 | 
			
		||||
    client.setDisplay("init", initLoadingDisplay);
 | 
			
		||||
    /**
 | 
			
		||||
     * 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 apge are
 | 
			
		||||
     * shown etc.
 | 
			
		||||
     * Lastly it also contains the object ResultsList which is a list.js
 | 
			
		||||
     * subclass which handles the visual reprensetnation of the query data.
 | 
			
		||||
     */
 | 
			
		||||
     let displayOptionsData = ResultsList.getDisplayOptions('display-options-form');
 | 
			
		||||
     ResultsList.options.page = displayOptionsData["resultsPerPage"];
 | 
			
		||||
     let resultsList = new ResultsList("result-list", ResultsList.options);
 | 
			
		||||
     let resultsMetaData = new MetaData();
 | 
			
		||||
     let results = new Results(new Data(), resultsList, resultsMetaData);
 | 
			
		||||
     // 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
 | 
			
		||||
    const listenForSession = new SocketEventListener('corpus_analysis_init',
 | 
			
		||||
                                                    recieveSession);
 | 
			
		||||
    const listenForQueryStatus = new SocketEventListener('corpus_analysis_query',
 | 
			
		||||
                                                       recieveQueryStatus);
 | 
			
		||||
    const listenForQueryData = new SocketEventListener('corpus_analysis_query_results',
 | 
			
		||||
                                                    recieveQueryData);
 | 
			
		||||
    client.setSocketEventListeners([listenForSession, listenForQueryStatus,
 | 
			
		||||
                                    listenForQueryData]);
 | 
			
		||||
    client.loadSocketEventListeners();
 | 
			
		||||
    // Session initialization
 | 
			
		||||
    client.requestSession();
 | 
			
		||||
    // Send a query and recieve its answer data
 | 
			
		||||
    let queryFormElement = document.getElementById("query-form");
 | 
			
		||||
    queryFormElement.addEventListener("submit", (event) => {
 | 
			
		||||
      try {
 | 
			
		||||
        /**
 | 
			
		||||
         * Selects first page of result list if pagination is already available
 | 
			
		||||
         * from an query submitted before.
 | 
			
		||||
         * This avoids confusion for the user e.g.: The user was on page 24
 | 
			
		||||
         * reviewing the results and issues a new query. He would not see any
 | 
			
		||||
         * results until the new results reach page 24 or he clicks on another
 | 
			
		||||
         * valid result page element from the new pagination.
 | 
			
		||||
         */
 | 
			
		||||
         let xpath = '//a[@class="page" and text()=1]';
 | 
			
		||||
         let firstPageElement = document.evaluate(xpath,
 | 
			
		||||
                                                  document,
 | 
			
		||||
                                                  null,
 | 
			
		||||
                                                  XPathResult.FIRST_ORDERED_NODE_TYPE,
 | 
			
		||||
                                                  null).singleNodeValue;
 | 
			
		||||
        firstPageElement.click();
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
      }
 | 
			
		||||
      // Prevent page from reloading on submit
 | 
			
		||||
      event.preventDefault();
 | 
			
		||||
      // Get query string and send query to server
 | 
			
		||||
      results.data.getQueryStr(queryFormElement);
 | 
			
		||||
      client.requestQueryData(results.data.query);
 | 
			
		||||
    });
 | 
			
		||||
   let displayOptionsData = ResultsList.getDisplayOptions('display-options-form');
 | 
			
		||||
   ResultsList.options.page = displayOptionsData["resultsPerPage"];
 | 
			
		||||
   let data = new Data();
 | 
			
		||||
   let resultsList = new ResultsList("result-list", ResultsList.options);
 | 
			
		||||
   let resultsMetaData = new MetaData();
 | 
			
		||||
   let results = new Results(data, resultsList, resultsMetaData);
 | 
			
		||||
   // make results part of the client
 | 
			
		||||
   client.results = results;
 | 
			
		||||
   console.info('Initialized the Results object.')
 | 
			
		||||
  // register listeners listening to socket.io events and load them
 | 
			
		||||
  const listenForSession = new SocketEventListener('corpus_analysis_init',
 | 
			
		||||
                                                  recieveSession);
 | 
			
		||||
  const listenForQueryStatus = new SocketEventListener('corpus_analysis_query',
 | 
			
		||||
                                                     recieveQueryStatus);
 | 
			
		||||
  const listenForQueryData = new SocketEventListener('corpus_analysis_query_results',
 | 
			
		||||
                                                  recieveQueryData);
 | 
			
		||||
  client.setSocketEventListeners([listenForSession, listenForQueryStatus,
 | 
			
		||||
                                  listenForQueryData]);
 | 
			
		||||
  client.loadSocketEventListeners();
 | 
			
		||||
  // Session initialization
 | 
			
		||||
  client.requestSession();
 | 
			
		||||
  // Send a query and recieve its answer data
 | 
			
		||||
  let queryFormElement = document.getElementById("query-form");
 | 
			
		||||
  queryFormElement.addEventListener("submit", (event) => {
 | 
			
		||||
    try {
 | 
			
		||||
      /**
 | 
			
		||||
       * Selects first page of result list if pagination is already available
 | 
			
		||||
       * from an query submitted before.
 | 
			
		||||
       * This avoids confusion for the user e.g.: The user was on page 24
 | 
			
		||||
       * reviewing the results and issues a new query. He would not see any
 | 
			
		||||
       * results until the new results reach page 24 or he clicks on another
 | 
			
		||||
       * valid result page element from the new pagination.
 | 
			
		||||
       */
 | 
			
		||||
      let firstPageElement = document.querySelector('a.page');
 | 
			
		||||
      firstPageElement.click();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      // No page element is present if first query is submitted.
 | 
			
		||||
    }
 | 
			
		||||
    // Prevent page from reloading on submit
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
    // Get query string and send query to server
 | 
			
		||||
    results.data.getQueryStr(queryFormElement);
 | 
			
		||||
    client.requestQueryData(results.data.query);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -107,8 +107,8 @@
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
<script type="module">
 | 
			
		||||
  import {RessourceList} from '../../static/js/nopaque.lists.js';
 | 
			
		||||
  class InformationUpdater {
 | 
			
		||||
    constructor(corpusId, foreignCorpusFlag) {
 | 
			
		||||
      this.corpusId = corpusId;
 | 
			
		||||
@@ -196,7 +196,8 @@
 | 
			
		||||
    nopaque.socket.emit("foreign_user_data_stream_init", {{ corpus.user_id }});
 | 
			
		||||
  });
 | 
			
		||||
  {% endif %}
 | 
			
		||||
  var corpusFilesList = new RessourceList("corpus-files", null, "CorpusFile");
 | 
			
		||||
 | 
			
		||||
  let corpusFilesList = new RessourceList("corpus-files", null, "CorpusFile");
 | 
			
		||||
  document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
    corpusFilesList._add({{ corpus_files|tojson|safe }});
 | 
			
		||||
  });
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ the selected sub results.-->
 | 
			
		||||
              disabled
 | 
			
		||||
              flat-interaction"
 | 
			
		||||
              type="submit"
 | 
			
		||||
              id="results-create">Create Results
 | 
			
		||||
              id="query-results-create">Create Results
 | 
			
		||||
        <i class="material-icons left">build</i>
 | 
			
		||||
      </button>
 | 
			
		||||
      <button id="query-results-export"
 | 
			
		||||
 
 | 
			
		||||
@@ -17,29 +17,27 @@ result.-->
 | 
			
		||||
      </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="col s12">
 | 
			
		||||
      <div class="progress hide" id="query-progress-bar">
 | 
			
		||||
        <div class="determinate"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <p>
 | 
			
		||||
        <span id="received-match-count">
 | 
			
		||||
        <span id="recieved-match-count">
 | 
			
		||||
        </span> of
 | 
			
		||||
        <span id="match-count"></span>
 | 
			
		||||
        <span id="total-match-count"></span>
 | 
			
		||||
        matches loaded.
 | 
			
		||||
        <br>
 | 
			
		||||
        Matches occured in
 | 
			
		||||
        <span id="text-lookup-count"></span>
 | 
			
		||||
        corpus files:
 | 
			
		||||
        <br>
 | 
			
		||||
        <span id=text-titles></span>
 | 
			
		||||
        <span id=text-lookup-titles></span>
 | 
			
		||||
      </p>
 | 
			
		||||
      {% if not imported %}
 | 
			
		||||
      <p id="query-results-user-feedback">
 | 
			
		||||
        <i class="material-icons">help</i>
 | 
			
		||||
        The Server is still sending your results.
 | 
			
		||||
      <p class="hide" id="query-results-user-feedback">
 | 
			
		||||
        <i class="material-icons tiny">help</i>
 | 
			
		||||
        Server is sending your results.
 | 
			
		||||
        Functions like "Export Results" and "Match Inspect" will be
 | 
			
		||||
        available after all matches have been loaded.
 | 
			
		||||
      </p>
 | 
			
		||||
      <div class="progress" id="query-results-progress">
 | 
			
		||||
        <div class="determinate" id="query-results-determinate"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      {% endif %}
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -150,11 +150,11 @@
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
  var corpusList = new RessourceList("corpora", nopaque.corporaSubscribers, "Corpus");
 | 
			
		||||
  var jobList = new RessourceList("jobs", nopaque.jobsSubscribers, "Job");
 | 
			
		||||
  var queryResultList = new RessourceList("query-results", nopaque.queryResultsSubscribers, "QueryResult");
 | 
			
		||||
<script type="module">
 | 
			
		||||
  import {RessourceList} from '../../static/js/nopaque.lists.js';
 | 
			
		||||
  let corpusList = new RessourceList("corpora", nopaque.corporaSubscribers, "Corpus");
 | 
			
		||||
  let jobList = new RessourceList("jobs", nopaque.jobsSubscribers, "Job");
 | 
			
		||||
  let queryResultList = new RessourceList("query-results", nopaque.queryResultsSubscribers, "QueryResult");
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -54,180 +54,150 @@
 | 
			
		||||
{% include 'modals/context_modal.html.j2' %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.Results.js') }}">
 | 
			
		||||
</script>
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.callbacks.js') }}">
 | 
			
		||||
</script>
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.InteractionElement.js') }}">
 | 
			
		||||
</script>
 | 
			
		||||
<script>
 | 
			
		||||
  // ###### global variables ######
 | 
			
		||||
  var full_result_json;
 | 
			
		||||
  var result_json;
 | 
			
		||||
  var receivedMatchCountElement;  // Nr. of loaded matches will be displayed in this element
 | 
			
		||||
  var textLookupCountElement  // Nr of texts the matches occured in will be shown in this element
 | 
			
		||||
  var textTitlesElement;  // matched text titles
 | 
			
		||||
  var progress;  // global progress value
 | 
			
		||||
  var queryResultsProgressElement;  // Div element holding the progress bar
 | 
			
		||||
  var expertModeSwitchElement; // Expert mode switch Element
 | 
			
		||||
  var matchCountElement;  // Total nr. of matches will be displayed in this element
 | 
			
		||||
  var interactionElements;  // Interaction elements and their parameters
 | 
			
		||||
  var contextModal;  // Modal to open on inspect for further match context
 | 
			
		||||
<script type="module">
 | 
			
		||||
/**
 | 
			
		||||
 * First Phase:
 | 
			
		||||
 * document content is loaded and scripts are being imported and executed
 | 
			
		||||
 */
 | 
			
		||||
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'
 | 
			
		||||
 | 
			
		||||
  // ###### Defining local scope variables
 | 
			
		||||
  let displayOptionsFormElement;  // Form holding the display informations
 | 
			
		||||
  let resultItems;  // array of built html result items row element. This is called when results are transmitted and being recieved
 | 
			
		||||
  let hitsPerPageInputElement;let contextPerItemElement;  // Form Element for display option
 | 
			
		||||
  let paginationElements;
 | 
			
		||||
  let inspectBtnElements;
 | 
			
		||||
  let metaDataModal;
 | 
			
		||||
  let showMetaDataButton
 | 
			
		||||
/**
 | 
			
		||||
 * Second Phase:
 | 
			
		||||
 * Asynchronus and event driven code
 | 
			
		||||
 */
 | 
			
		||||
document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
  // Initialize the CorpusAnalysisClient
 | 
			
		||||
  const client = new CorpusAnalysisClient({'logging': true,
 | 
			
		||||
                                           'dynamicMode': false});
 | 
			
		||||
  console.info("CorpusAnalysisClient created as client:", client);
 | 
			
		||||
  // Set up display elements which hare show depending on the client status
 | 
			
		||||
  client.getHTMLElements(['#query-display']);
 | 
			
		||||
  const queryDisplay = new CorpusAnalysisDisplay(client.queryDisplay);
 | 
			
		||||
  // Register those display elements to client
 | 
			
		||||
  client.setDisplay("query", queryDisplay);
 | 
			
		||||
  /**
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
   let displayOptionsData = ResultsList.getDisplayOptions('display-options-form');
 | 
			
		||||
   ResultsList.options.page = displayOptionsData["resultsPerPage"];
 | 
			
		||||
   let data = new Data();
 | 
			
		||||
   let resultsList = new ResultsList("result-list", ResultsList.options);
 | 
			
		||||
   let resultsMetaData = new MetaData();
 | 
			
		||||
   let results = new Results(data, resultsList, resultsMetaData);
 | 
			
		||||
   // make results part of the client
 | 
			
		||||
   client.results = results;
 | 
			
		||||
   // inits some object keys and values
 | 
			
		||||
   client.results.clearAll();
 | 
			
		||||
   console.info('Initialized the Results object.')
 | 
			
		||||
   // init some modals
 | 
			
		||||
   let deleteOverlay = () => {
 | 
			
		||||
     let overlay = document.getElementsByClassName("modal-overlay")[0];
 | 
			
		||||
     overlay.remove();
 | 
			
		||||
   };
 | 
			
		||||
   client.getHTMLElements(['#meta-data-modal'])
 | 
			
		||||
   client.metaDataModal = M.Modal.init(client.metaDataModal,
 | 
			
		||||
                                {'preventScrolling': false,
 | 
			
		||||
                                 'opacity': 0.0,
 | 
			
		||||
                                 'dismissible': false,
 | 
			
		||||
                                 'onOpenEnd': deleteOverlay});
 | 
			
		||||
  // saving imported data into client object
 | 
			
		||||
  const payload = {{ query_result_file_content|tojson|safe }};
 | 
			
		||||
 | 
			
		||||
  // ###### Initializing variables ######
 | 
			
		||||
  displayOptionsFormElement = document.getElementById("display-options-form");
 | 
			
		||||
  resultItems = [];
 | 
			
		||||
  receivedMatchCountElement = document.getElementById("received-match-count");
 | 
			
		||||
  textLookupCountElement = document.getElementById("text-lookup-count");
 | 
			
		||||
  textTitlesElement = document.getElementById("text-titles");
 | 
			
		||||
  queryResultsProgressElement = document.getElementById("query-results-progress");
 | 
			
		||||
  expertModeSwitchElement = document.getElementById("display-options-form-expert_mode");
 | 
			
		||||
  matchCountElement = document.getElementById("match-count");
 | 
			
		||||
  hitsPerPageInputElement = document.getElementById("display-options-form-results_per_page");
 | 
			
		||||
  contextPerItemElement = document.getElementById("display-options-form-result_context");
 | 
			
		||||
  paginationElements = document.getElementsByClassName("pagination");
 | 
			
		||||
  contextModal = document.getElementById("context-modal");
 | 
			
		||||
  metaDataModal = document.getElementById("meta-data-modal");
 | 
			
		||||
  showMetaDataButton = document.getElementById("show-metadata");
 | 
			
		||||
 | 
			
		||||
  // js list options
 | 
			
		||||
  displayOptionsData = ResultsList.getDisplayOptions(displayOptionsFormElement);
 | 
			
		||||
  resultsListOptions = {page: displayOptionsData["resultsPerPage"],
 | 
			
		||||
  pagination: [{
 | 
			
		||||
      name: "paginationTop",
 | 
			
		||||
      paginationClass: "paginationTop",
 | 
			
		||||
      innerWindow: 8,
 | 
			
		||||
      outerWindow: 1
 | 
			
		||||
    }, {
 | 
			
		||||
      paginationClass: "paginationBottom",
 | 
			
		||||
      innerWindow: 8,
 | 
			
		||||
      outerWindow: 1
 | 
			
		||||
    }],
 | 
			
		||||
    valueNames: ["titles", "lc", "c", "rc", {data: ["index"]}],
 | 
			
		||||
    item: `<span></span>`
 | 
			
		||||
  };
 | 
			
		||||
//
 | 
			
		||||
//   // Initialization of interactionElemnts
 | 
			
		||||
//   // An interactionElement is an object identifing a switch or button via
 | 
			
		||||
//   // htmlID. Callbacks are set for these elements which will be triggered on
 | 
			
		||||
//   // a pagination interaction by the user or if the status of the element has
 | 
			
		||||
//   // been altered. (Like the switche has ben turned on or off).
 | 
			
		||||
//   interactionElements = new InteractionElements();
 | 
			
		||||
//   let expertModeInteraction = new InteractionElement("display-options-form-expert_mode");
 | 
			
		||||
//   expertModeInteraction.setCallback("on",
 | 
			
		||||
//                                     results.jsList.expertModeOn,
 | 
			
		||||
//                                     results.jsList,
 | 
			
		||||
//                                     ["query-display"])
 | 
			
		||||
//   expertModeInteraction.setCallback("off",
 | 
			
		||||
//                                     results.jsList.expertModeOff,
 | 
			
		||||
//                                     results.jsList,
 | 
			
		||||
//                                     ["query-display"])
 | 
			
		||||
//
 | 
			
		||||
//   let activateInspectInteraction = new InteractionElement("inspect",
 | 
			
		||||
//                                                           false);
 | 
			
		||||
//   activateInspectInteraction.setCallback("noCheck",
 | 
			
		||||
//                                           results.jsList.activateInspect,
 | 
			
		||||
//                                           results.jsList);
 | 
			
		||||
//
 | 
			
		||||
//   let changeContextInteraction = new InteractionElement("display-options-form-results_per_page",
 | 
			
		||||
//                                                         false);
 | 
			
		||||
//   changeContextInteraction.setCallback("noCheck",
 | 
			
		||||
//                                       results.jsList.changeContext,
 | 
			
		||||
//                                       results.jsList)
 | 
			
		||||
//   interactionElements.addInteractions([expertModeInteraction, activateInspectInteraction, changeContextInteraction]);
 | 
			
		||||
//
 | 
			
		||||
//   // checks if a change for every interactionElement happens and executes
 | 
			
		||||
//   // the callbacks accordingly
 | 
			
		||||
//   interactionElements.onChangeExecute();
 | 
			
		||||
//
 | 
			
		||||
//   // eventListener if pagination is used to apply new context size to new page
 | 
			
		||||
//   // and also activate inspect match if progress is 100
 | 
			
		||||
//   // also adds more interaction buttons like add to sub results
 | 
			
		||||
//   for (let element of paginationElements) {
 | 
			
		||||
//     element.addEventListener("click", (event) => {
 | 
			
		||||
//       results.jsList.pageChangeEventInteractionHandler(interactionElements);
 | 
			
		||||
//     });
 | 
			
		||||
//   }
 | 
			
		||||
//
 | 
			
		||||
  // render results directly with callbacks because we are not in dynamic mode
 | 
			
		||||
  querySetup(payload, client);
 | 
			
		||||
  queryRenderResults(payload, client);
 | 
			
		||||
 | 
			
		||||
  document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
    // Initialize some Modals
 | 
			
		||||
    contextModal = M.Modal.init(contextModal, {"dismissible": true});
 | 
			
		||||
 | 
			
		||||
    // ###### recreating chunk structure to reuse callback queryRenderResults()
 | 
			
		||||
    full_result_json = {{ query_result_file_content|tojson|safe }};
 | 
			
		||||
    result_json = {};
 | 
			
		||||
    result_json["chunk"] = {};
 | 
			
		||||
    result_json.chunk["cpos_lookup"] = full_result_json.cpos_lookup;
 | 
			
		||||
    result_json.chunk["cpos_ranges"] = full_result_json.cpos_ranges;
 | 
			
		||||
    result_json.chunk["matches"] = full_result_json.matches;
 | 
			
		||||
    result_json.chunk["text_lookup"] = full_result_json.text_lookup;
 | 
			
		||||
 | 
			
		||||
    // Init corpus analysis components
 | 
			
		||||
    data = new Data();
 | 
			
		||||
    resultsList = new ResultsList("result-list", resultsListOptions);
 | 
			
		||||
    resultsMetaData = new MetaData();
 | 
			
		||||
    results = new Results(data, resultsList, resultsMetaData);
 | 
			
		||||
    results.clearAll();  // inits some object keys and values
 | 
			
		||||
    // init some modals
 | 
			
		||||
    let deleteOverlay = () => {
 | 
			
		||||
      let overlay = document.getElementsByClassName("modal-overlay")[0];
 | 
			
		||||
      overlay.remove();
 | 
			
		||||
    };
 | 
			
		||||
    metaDataModal = M.Modal.init(metaDataModal, {"preventScrolling": false,
 | 
			
		||||
                                 "opacity": 0.0,
 | 
			
		||||
                                 "dismissible": false,
 | 
			
		||||
                                 "onOpenEnd": deleteOverlay});
 | 
			
		||||
 | 
			
		||||
    // setting some initial values for user feedback
 | 
			
		||||
    matchCountElement.innerText = full_result_json.match_count;
 | 
			
		||||
 | 
			
		||||
    // Initialization of interactionElemnts
 | 
			
		||||
    // An interactionElement is an object identifing a switch or button via
 | 
			
		||||
    // htmlID. Callbacks are set for these elements which will be triggered on
 | 
			
		||||
    // a pagination interaction by the user or if the status of the element has
 | 
			
		||||
    // been altered. (Like the switche has ben turned on or off).
 | 
			
		||||
    interactionElements = new InteractionElements();
 | 
			
		||||
    let expertModeInteraction = new InteractionElement("display-options-form-expert_mode");
 | 
			
		||||
    expertModeInteraction.setCallback("on",
 | 
			
		||||
                                      results.jsList.expertModeOn,
 | 
			
		||||
                                      results.jsList,
 | 
			
		||||
                                      ["query-display"])
 | 
			
		||||
    expertModeInteraction.setCallback("off",
 | 
			
		||||
                                      results.jsList.expertModeOff,
 | 
			
		||||
                                      results.jsList,
 | 
			
		||||
                                      ["query-display"])
 | 
			
		||||
 | 
			
		||||
    let activateInspectInteraction = new InteractionElement("inspect",
 | 
			
		||||
                                                            false);
 | 
			
		||||
    activateInspectInteraction.setCallback("noCheck",
 | 
			
		||||
                                            results.jsList.activateInspect,
 | 
			
		||||
                                            results.jsList);
 | 
			
		||||
 | 
			
		||||
    let changeContextInteraction = new InteractionElement("display-options-form-results_per_page",
 | 
			
		||||
                                                          false);
 | 
			
		||||
    changeContextInteraction.setCallback("noCheck",
 | 
			
		||||
                                        results.jsList.changeContext,
 | 
			
		||||
                                        results.jsList)
 | 
			
		||||
    interactionElements.addInteractions([expertModeInteraction, activateInspectInteraction, changeContextInteraction]);
 | 
			
		||||
 | 
			
		||||
    // checks if a change for every interactionElement happens and executes
 | 
			
		||||
    // the callbacks accordingly
 | 
			
		||||
    interactionElements.onChangeExecute();
 | 
			
		||||
 | 
			
		||||
    // eventListener if pagination is used to apply new context size to new page
 | 
			
		||||
    // and also activate inspect match if progress is 100
 | 
			
		||||
    // also adds more interaction buttons like add to sub results
 | 
			
		||||
    for (let element of paginationElements) {
 | 
			
		||||
      element.addEventListener("click", (event) => {
 | 
			
		||||
        results.jsList.pageChangeEventInteractionHandler(interactionElements);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // render results in table imported parameter is true
 | 
			
		||||
    queryRenderResults(result_json, true);
 | 
			
		||||
 | 
			
		||||
    // ### Show corpus Metadata
 | 
			
		||||
    showMetaDataButton.onclick = () => {
 | 
			
		||||
      metaDataModal.open();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // live update of hits per page if hits per page value is changed
 | 
			
		||||
    let changeHitsPerPageBind = results.jsList.changeHitsPerPage.bind(results.jsList);
 | 
			
		||||
    hitsPerPageInputElement.onchange = changeHitsPerPageBind;
 | 
			
		||||
 | 
			
		||||
    // live update of lr context per item if context value is changed
 | 
			
		||||
    contextPerItemElement.onchange = results.jsList.changeContext;
 | 
			
		||||
 | 
			
		||||
    // new insepct event listener makeing use of javascript bubbleing
 | 
			
		||||
    let resultsTable = document.getElementById("query-results");
 | 
			
		||||
    resultsTable.addEventListener("click", (event) => {
 | 
			
		||||
      if (event.target.classList.contains("inspect-btn")) {
 | 
			
		||||
        const dataIndex = event.target.closest("tr").dataset.index;
 | 
			
		||||
        const fakeResponse = results.jsList.createFakeResponse();
 | 
			
		||||
        results.jsList.showMatchContext(fakeResponse);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // 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"});
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
//   // ### Show corpus Metadata
 | 
			
		||||
//   showMetaDataButton.onclick = () => {
 | 
			
		||||
//     metaDataModal.open();
 | 
			
		||||
//   };
 | 
			
		||||
//
 | 
			
		||||
//   // live update of hits per page if hits per page value is changed
 | 
			
		||||
//   let changeHitsPerPageBind = results.jsList.changeHitsPerPage.bind(results.jsList);
 | 
			
		||||
//   hitsPerPageInputElement.onchange = changeHitsPerPageBind;
 | 
			
		||||
//
 | 
			
		||||
//   // live update of lr context per item if context value is changed
 | 
			
		||||
//   contextPerItemElement.onchange = results.jsList.changeContext;
 | 
			
		||||
//
 | 
			
		||||
//   // new insepct event listener makeing use of javascript bubbleing
 | 
			
		||||
//   let resultsTable = document.getElementById("query-results");
 | 
			
		||||
//   resultsTable.addEventListener("click", (event) => {
 | 
			
		||||
//     if (event.target.classList.contains("inspect-btn")) {
 | 
			
		||||
//       const dataIndex = event.target.closest("tr").dataset.index;
 | 
			
		||||
//       const fakeResponse = results.jsList.createFakeResponse();
 | 
			
		||||
//       results.jsList.showMatchContext(fakeResponse);
 | 
			
		||||
//     }
 | 
			
		||||
//   });
 | 
			
		||||
//
 | 
			
		||||
//   // scroll to top button if user scrolled down the list
 | 
			
		||||
//   let headline = document.querySelector(".headline");
 | 
			
		||||
//   let scrollToTop = document.querySelector("#menu-scroll-to-top-div");
 | 
			
		||||
//   window.addEventListener("scroll", (event) => {
 | 
			
		||||
//     if (pageYOffset > 250) {
 | 
			
		||||
//       scrollToTop.classList.toggle("hide", false);
 | 
			
		||||
//     } else {
 | 
			
		||||
//       scrollToTop.classList.toggle("hide", true);
 | 
			
		||||
//     }
 | 
			
		||||
//   });
 | 
			
		||||
//   scrollToTop.onclick = () => {
 | 
			
		||||
//     headline.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
 | 
			
		||||
//   };
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										233
									
								
								web/app/templates/query_results/inspect.html.j2.bak
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								web/app/templates/query_results/inspect.html.j2.bak
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,233 @@
 | 
			
		||||
{% extends "nopaque.html.j2" %}
 | 
			
		||||
 | 
			
		||||
{% set headline = ' ' %}
 | 
			
		||||
 | 
			
		||||
{% set full_width = True %}
 | 
			
		||||
{% set imported = True %}
 | 
			
		||||
 | 
			
		||||
{% block page_content %}
 | 
			
		||||
 | 
			
		||||
<div class="col s12">
 | 
			
		||||
  <div class="card">
 | 
			
		||||
    <div class="card-content" style="padding-top: 5px;
 | 
			
		||||
                             padding-bottom: 0px;">
 | 
			
		||||
      <!-- Query form -->
 | 
			
		||||
      <div class="row">
 | 
			
		||||
      <form id="query-form">
 | 
			
		||||
          <div class="col s12 m10">
 | 
			
		||||
            <div class="input-field">
 | 
			
		||||
              <i class="material-icons prefix">search</i>
 | 
			
		||||
              <input disabled value="{{ query_metadata.query|escape }}" id="disabled" type="text" class="validate">
 | 
			
		||||
          <label for="disabled">Query</label>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col s12 m2 right-align">
 | 
			
		||||
            <br class="hide-on-small-only">
 | 
			
		||||
          </div>
 | 
			
		||||
      </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<!-- entire results div/card -->
 | 
			
		||||
<div class="col s12" id="query-display">
 | 
			
		||||
  <div class="card">
 | 
			
		||||
    <div class="card-content" id="result-list" style="overflow: hidden;">
 | 
			
		||||
      <div class=" row show-on-success">
 | 
			
		||||
        {% include 'interactions/infos.html.j2' %}
 | 
			
		||||
        {% include 'interactions/display.html.j2' %}
 | 
			
		||||
        {% include 'interactions/analysis.html.j2' %}
 | 
			
		||||
        {% include 'interactions/cite.html.j2' %}
 | 
			
		||||
      </div>
 | 
			
		||||
      {% include 'tables/query_results.html.j2' %}
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<!-- Scroll to top element -->
 | 
			
		||||
{% include 'interactions/scroll_to_top.html.j2' %}
 | 
			
		||||
 | 
			
		||||
<!-- Modals -->
 | 
			
		||||
{% include 'modals/show_metadata.html.j2' %}
 | 
			
		||||
{% include 'modals/show_text_details.html.j2' %}
 | 
			
		||||
{% include 'modals/context_modal.html.j2' %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.Results.js') }}">
 | 
			
		||||
</script>
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.callbacks.js') }}">
 | 
			
		||||
</script>
 | 
			
		||||
<script src="{{ url_for('static', filename='js/nopaque.InteractionElement.js') }}">
 | 
			
		||||
</script>
 | 
			
		||||
<script>
 | 
			
		||||
  // ###### global variables ######
 | 
			
		||||
  var full_result_json;
 | 
			
		||||
  var result_json;
 | 
			
		||||
  var receivedMatchCountElement;  // Nr. of loaded matches will be displayed in this element
 | 
			
		||||
  var textLookupCountElement  // Nr of texts the matches occured in will be shown in this element
 | 
			
		||||
  var textTitlesElement;  // matched text titles
 | 
			
		||||
  var progress;  // global progress value
 | 
			
		||||
  var queryResultsProgressElement;  // Div element holding the progress bar
 | 
			
		||||
  var expertModeSwitchElement; // Expert mode switch Element
 | 
			
		||||
  var matchCountElement;  // Total nr. of matches will be displayed in this element
 | 
			
		||||
  var interactionElements;  // Interaction elements and their parameters
 | 
			
		||||
  var contextModal;  // Modal to open on inspect for further match context
 | 
			
		||||
 | 
			
		||||
  // ###### Defining local scope variables
 | 
			
		||||
  let displayOptionsFormElement;  // Form holding the display informations
 | 
			
		||||
  let resultItems;  // array of built html result items row element. This is called when results are transmitted and being recieved
 | 
			
		||||
  let hitsPerPageInputElement;let contextPerItemElement;  // Form Element for display option
 | 
			
		||||
  let paginationElements;
 | 
			
		||||
  let inspectBtnElements;
 | 
			
		||||
  let metaDataModal;
 | 
			
		||||
  let showMetaDataButton
 | 
			
		||||
 | 
			
		||||
  // ###### Initializing variables ######
 | 
			
		||||
  displayOptionsFormElement = document.getElementById("display-options-form");
 | 
			
		||||
  resultItems = [];
 | 
			
		||||
  receivedMatchCountElement = document.getElementById("received-match-count");
 | 
			
		||||
  textLookupCountElement = document.getElementById("text-lookup-count");
 | 
			
		||||
  textTitlesElement = document.getElementById("text-titles");
 | 
			
		||||
  queryResultsProgressElement = document.getElementById("query-results-progress");
 | 
			
		||||
  expertModeSwitchElement = document.getElementById("display-options-form-expert_mode");
 | 
			
		||||
  matchCountElement = document.getElementById("match-count");
 | 
			
		||||
  hitsPerPageInputElement = document.getElementById("display-options-form-results_per_page");
 | 
			
		||||
  contextPerItemElement = document.getElementById("display-options-form-result_context");
 | 
			
		||||
  paginationElements = document.getElementsByClassName("pagination");
 | 
			
		||||
  contextModal = document.getElementById("context-modal");
 | 
			
		||||
  metaDataModal = document.getElementById("meta-data-modal");
 | 
			
		||||
  showMetaDataButton = document.getElementById("show-metadata");
 | 
			
		||||
 | 
			
		||||
  // js list options
 | 
			
		||||
  displayOptionsData = ResultsList.getDisplayOptions(displayOptionsFormElement);
 | 
			
		||||
  resultsListOptions = {page: displayOptionsData["resultsPerPage"],
 | 
			
		||||
  pagination: [{
 | 
			
		||||
      name: "paginationTop",
 | 
			
		||||
      paginationClass: "paginationTop",
 | 
			
		||||
      innerWindow: 8,
 | 
			
		||||
      outerWindow: 1
 | 
			
		||||
    }, {
 | 
			
		||||
      paginationClass: "paginationBottom",
 | 
			
		||||
      innerWindow: 8,
 | 
			
		||||
      outerWindow: 1
 | 
			
		||||
    }],
 | 
			
		||||
    valueNames: ["titles", "lc", "c", "rc", {data: ["index"]}],
 | 
			
		||||
    item: `<span></span>`
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
    // Initialize some Modals
 | 
			
		||||
    contextModal = M.Modal.init(contextModal, {"dismissible": true});
 | 
			
		||||
 | 
			
		||||
    // ###### recreating chunk structure to reuse callback queryRenderResults()
 | 
			
		||||
    full_result_json = {{ query_result_file_content|tojson|safe }};
 | 
			
		||||
    result_json = {};
 | 
			
		||||
    result_json["chunk"] = {};
 | 
			
		||||
    result_json.chunk["cpos_lookup"] = full_result_json.cpos_lookup;
 | 
			
		||||
    result_json.chunk["cpos_ranges"] = full_result_json.cpos_ranges;
 | 
			
		||||
    result_json.chunk["matches"] = full_result_json.matches;
 | 
			
		||||
    result_json.chunk["text_lookup"] = full_result_json.text_lookup;
 | 
			
		||||
 | 
			
		||||
    // Init corpus analysis components
 | 
			
		||||
    data = new Data();
 | 
			
		||||
    resultsList = new ResultsList("result-list", resultsListOptions);
 | 
			
		||||
    resultsMetaData = new MetaData();
 | 
			
		||||
    results = new Results(data, resultsList, resultsMetaData);
 | 
			
		||||
    results.clearAll();  // inits some object keys and values
 | 
			
		||||
    // init some modals
 | 
			
		||||
    let deleteOverlay = () => {
 | 
			
		||||
      let overlay = document.getElementsByClassName("modal-overlay")[0];
 | 
			
		||||
      overlay.remove();
 | 
			
		||||
    };
 | 
			
		||||
    metaDataModal = M.Modal.init(metaDataModal, {"preventScrolling": false,
 | 
			
		||||
                                 "opacity": 0.0,
 | 
			
		||||
                                 "dismissible": false,
 | 
			
		||||
                                 "onOpenEnd": deleteOverlay});
 | 
			
		||||
 | 
			
		||||
    // setting some initial values for user feedback
 | 
			
		||||
    matchCountElement.innerText = full_result_json.match_count;
 | 
			
		||||
 | 
			
		||||
    // Initialization of interactionElemnts
 | 
			
		||||
    // An interactionElement is an object identifing a switch or button via
 | 
			
		||||
    // htmlID. Callbacks are set for these elements which will be triggered on
 | 
			
		||||
    // a pagination interaction by the user or if the status of the element has
 | 
			
		||||
    // been altered. (Like the switche has ben turned on or off).
 | 
			
		||||
    interactionElements = new InteractionElements();
 | 
			
		||||
    let expertModeInteraction = new InteractionElement("display-options-form-expert_mode");
 | 
			
		||||
    expertModeInteraction.setCallback("on",
 | 
			
		||||
                                      results.jsList.expertModeOn,
 | 
			
		||||
                                      results.jsList,
 | 
			
		||||
                                      ["query-display"])
 | 
			
		||||
    expertModeInteraction.setCallback("off",
 | 
			
		||||
                                      results.jsList.expertModeOff,
 | 
			
		||||
                                      results.jsList,
 | 
			
		||||
                                      ["query-display"])
 | 
			
		||||
 | 
			
		||||
    let activateInspectInteraction = new InteractionElement("inspect",
 | 
			
		||||
                                                            false);
 | 
			
		||||
    activateInspectInteraction.setCallback("noCheck",
 | 
			
		||||
                                            results.jsList.activateInspect,
 | 
			
		||||
                                            results.jsList);
 | 
			
		||||
 | 
			
		||||
    let changeContextInteraction = new InteractionElement("display-options-form-results_per_page",
 | 
			
		||||
                                                          false);
 | 
			
		||||
    changeContextInteraction.setCallback("noCheck",
 | 
			
		||||
                                        results.jsList.changeContext,
 | 
			
		||||
                                        results.jsList)
 | 
			
		||||
    interactionElements.addInteractions([expertModeInteraction, activateInspectInteraction, changeContextInteraction]);
 | 
			
		||||
 | 
			
		||||
    // checks if a change for every interactionElement happens and executes
 | 
			
		||||
    // the callbacks accordingly
 | 
			
		||||
    interactionElements.onChangeExecute();
 | 
			
		||||
 | 
			
		||||
    // eventListener if pagination is used to apply new context size to new page
 | 
			
		||||
    // and also activate inspect match if progress is 100
 | 
			
		||||
    // also adds more interaction buttons like add to sub results
 | 
			
		||||
    for (let element of paginationElements) {
 | 
			
		||||
      element.addEventListener("click", (event) => {
 | 
			
		||||
        results.jsList.pageChangeEventInteractionHandler(interactionElements);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // render results in table imported parameter is true
 | 
			
		||||
    queryRenderResults(result_json, true);
 | 
			
		||||
 | 
			
		||||
    // ### Show corpus Metadata
 | 
			
		||||
    showMetaDataButton.onclick = () => {
 | 
			
		||||
      metaDataModal.open();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // live update of hits per page if hits per page value is changed
 | 
			
		||||
    let changeHitsPerPageBind = results.jsList.changeHitsPerPage.bind(results.jsList);
 | 
			
		||||
    hitsPerPageInputElement.onchange = changeHitsPerPageBind;
 | 
			
		||||
 | 
			
		||||
    // live update of lr context per item if context value is changed
 | 
			
		||||
    contextPerItemElement.onchange = results.jsList.changeContext;
 | 
			
		||||
 | 
			
		||||
    // new insepct event listener makeing use of javascript bubbleing
 | 
			
		||||
    let resultsTable = document.getElementById("query-results");
 | 
			
		||||
    resultsTable.addEventListener("click", (event) => {
 | 
			
		||||
      if (event.target.classList.contains("inspect-btn")) {
 | 
			
		||||
        const dataIndex = event.target.closest("tr").dataset.index;
 | 
			
		||||
        const fakeResponse = results.jsList.createFakeResponse();
 | 
			
		||||
        results.jsList.showMatchContext(fakeResponse);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // scroll to top button if user scrolled down the list
 | 
			
		||||
    let headline = document.querySelector(".headline");
 | 
			
		||||
    let scrollToTop = document.querySelector("#menu-scroll-to-top-div");
 | 
			
		||||
    window.addEventListener("scroll", (event) => {
 | 
			
		||||
      if (pageYOffset > 250) {
 | 
			
		||||
        scrollToTop.classList.toggle("hide", false);
 | 
			
		||||
      } else {
 | 
			
		||||
        scrollToTop.classList.toggle("hide", true);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    scrollToTop.onclick = () => {
 | 
			
		||||
      headline.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@@ -83,8 +83,9 @@
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
  var corpusList = new RessourceList("corpora", nopaque.corporaSubscribers, "Corpus");
 | 
			
		||||
  var queryResultList = new RessourceList("query-results", nopaque.queryResultsSubscribers, "QueryResult");
 | 
			
		||||
<script type="module">
 | 
			
		||||
  import {RessourceList} from '../../static/js/nopaque.lists.js';
 | 
			
		||||
  let corpusList = new RessourceList("corpora", nopaque.corporaSubscribers, "Corpus");
 | 
			
		||||
  let queryResultList = new RessourceList("query-results", nopaque.queryResultsSubscribers, "QueryResult");
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user