Rework corpora/query results

This commit is contained in:
Patrick Jentsch 2020-10-28 16:13:41 +01:00
parent 9c36ed3cc8
commit ffa7a7812a
5 changed files with 280 additions and 255 deletions
web/app

@ -51,8 +51,7 @@ def corpus(corpus_id):
title=corpus_file.title, title=corpus_file.title,
publishing_year=corpus_file.publishing_year, publishing_year=corpus_file.publishing_year,
corpus_id=corpus.id, corpus_id=corpus.id,
id=corpus_file.id id=corpus_file.id)
)
for corpus_file in corpus.files] for corpus_file in corpus.files]
return render_template('corpora/corpus.html.j2', return render_template('corpora/corpus.html.j2',
corpus=corpus, corpus=corpus,

@ -1,14 +1,15 @@
<!-- HTML to allow the user to change how the results are being displayed.--> {% import 'materialize/wtf.html.j2' as wtf %}
<!-- HTML to allow the user to change how the results are being displayed.-->
<div class="col s12 m3 l2" id="display"> <div class="col s12 m3 l2" id="display">
<h6 style="margin-top: 0px;">Display</h6> <h6 style="margin-top: 0px;">Display</h6>
<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">
<form id="display-options-form"> <form id="display-options-form">
{{ M.render_field(display_options_form.results_per_page, {{ wtf.render_field(display_options_form.results_per_page,
material_icon='format_list_numbered') }} material_icon='format_list_numbered') }}
{{ M.render_field(display_options_form.result_context, {{ wtf.render_field(display_options_form.result_context,
material_icon='short_text') }} material_icon='short_text') }}
<div class="col s12" style="line-height: 38px;"> <div class="col s12" style="line-height: 38px;">
<div class="col s8"> <div class="col s8">
@ -27,4 +28,3 @@
</div> </div>
</div> </div>
</div> </div>

@ -1,33 +1,42 @@
{% extends "nopaque.html.j2" %} {% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %} {% block page_content %}
<div class="col s12 m4"> <div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">{{ title }}</h1>
</div>
<div class="col s12 m4">
<p>Fill out the following form to upload and view your exported query data from the corpus analsis.</p> <p>Fill out the following form to upload and view your exported query data from the corpus analsis.</p>
<a class="waves-effect waves-light btn" href="{{ url_for('main.dashboard') }}"><i class="material-icons left">arrow_back</i>Back to dashboard</a> <a class="waves-effect waves-light btn" href="{{ url_for('main.dashboard') }}"><i class="material-icons left">arrow_back</i>Back to dashboard</a>
</div> </div>
<div class="col s12 m8"> <div class="col s12 m8">
<form class="nopaque-submit-form" data-progress-modal="progress-modal"> <form class="nopaque-submit-form" data-progress-modal="progress-modal">
<div class="card"> <div class="card">
<div class="card-content"> <div class="card-content">
{{ add_query_result_form.hidden_tag() }} {{ add_query_result_form.hidden_tag() }}
<div class="row"> <div class="row">
<div class="col s12 m4"> <div class="col s12 m4">
{{ M.render_field(add_query_result_form.title, data_length='32', material_icon='title') }} {{ wtf.render_field(add_query_result_form.title, data_length='32', material_icon='title') }}
</div> </div>
<div class="col s12 m8"> <div class="col s12 m8">
{{ M.render_field(add_query_result_form.description, data_length='255', material_icon='description') }} {{ wtf.render_field(add_query_result_form.description, data_length='255', material_icon='description') }}
</div> </div>
<div class="col s12"> <div class="col s12">
{{ M.render_field(add_query_result_form.file, accept='.json', placeholder='Choose your .json file') }} {{ wtf.render_field(add_query_result_form.file, accept='.json', placeholder='Choose your .json file') }}
</div> </div>
</div> </div>
</div> </div>
<div class="card-action right-align"> <div class="card-action right-align">
{{ M.render_field(add_query_result_form.submit, material_icon='send') }} {{ wtf.render_field(add_query_result_form.submit, material_icon='send') }}
</div> </div>
</div> </div>
</form> </form>
</div>
</div>
</div> </div>
<div id="progress-modal" class="modal"> <div id="progress-modal" class="modal">

@ -1,12 +1,14 @@
{% extends "nopaque.html.j2" %} {% extends "nopaque.html.j2" %}
{% from '_colors.html.j2' import colors %}
{% set headline = ' ' %} {% set scheme_primary_color = colors.corpus_analysis_darken %}
{% set scheme_secondary_color = colors.corpus_analysis %}
{% set full_width = True %} {% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
{% block page_content %} {% block page_content %}
{{ Macros.insert_color_scheme(corpus_analysis_color_darken) }} <div class="row">
<div class="col s12"> <div class="col s12">
<div class="card"> <div class="card">
<div class="card-content" style="padding-top: 5px; <div class="card-content" style="padding-top: 5px;
padding-bottom: 0px;"> padding-bottom: 0px;">
@ -27,10 +29,10 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- entire results div/card --> <!-- entire results div/card -->
<div class="col s12" id="query-display"> <div class="col s12" id="query-display">
<div class="card"> <div class="card">
<div class="card-content" id="result-list" style="overflow: hidden;"> <div class="card-content" id="result-list" style="overflow: hidden;">
<div class="row" id="interactions-menu"> <div class="row" id="interactions-menu">
@ -48,17 +50,21 @@
{% include 'tables/query_results.html.j2' %} {% include 'tables/query_results.html.j2' %}
</div> </div>
</div> </div>
</div>
</div> </div>
<!-- Scroll to top element --> {# Import modals #}
{% include 'corpora/interactions/scroll_to_top.html.j2' %}
<!-- Modals -->
{% include 'modals/show_metadata.html.j2' %} {% include 'modals/show_metadata.html.j2' %}
{% include 'modals/show_corpus_files.html.j2' %} {% include 'modals/show_corpus_files.html.j2' %}
{% include 'modals/context_modal.html.j2' %} {% include 'modals/context_modal.html.j2' %}
<!-- Scroll to top element -->
{% include 'corpora/interactions/scroll_to_top.html.j2' %}
{% endblock page_content %}
{% block scripts %}
{{ super() }}
<script type="module"> <script type="module">
/** /**
* First Phase: * First Phase:
@ -117,56 +123,55 @@ import {
* Second Phase: * Second Phase:
* Asynchronus and event driven code. * Asynchronus and event driven code.
*/ */
document.addEventListener("DOMContentLoaded", () => { /**
/**
* Initializing the results object as a model holding all the data of a * Initializing the results object as a model holding all the data of a
* query. Also holds the metadata of one query and results data. * query. Also holds the metadata of one query and results data.
* After that initialize the ResultsList object as the View handeling the * After that initialize the ResultsList object as the View handeling the
* representation of the data for the user. * representation of the data for the user.
*/ */
let results = new Results(); let results = new Results();
let resultsList = new ResultsList('result-list', ResultsList.options); let resultsList = new ResultsList('result-list', ResultsList.options);
// Import results data from json file. // Import results data from json file.
const resultsJson = {{ query_result_file_content|tojson|safe }}; const resultsJson = {{ query_result_file_content|tojson|safe }};
// Import metadata from DB passed to this view // Import metadata from DB passed to this view
const metaDataJson = {{ query_metadata|tojson|safe }}; const metaDataJson = {{ query_metadata|tojson|safe }};
// Initialize the client with dynamicMode set to false. // Initialize the client with dynamicMode set to false.
const client = new Client({'logging': true, const client = new Client({'logging': true,
'dynamicMode': false, 'dynamicMode': false,
'fullContext': metaDataJson.fullContext}); 'fullContext': metaDataJson.fullContext});
/** /**
* Register needed listeners and their callbacks. But we will * Register needed listeners and their callbacks. But we will
* just call the attached callbacks manually. Because dynamicMode is false. * just call the attached callbacks manually. Because dynamicMode is false.
*/ */
const listenForQueryStatus = new ClientEventListener('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 ClientEventListener('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]);
// Set the event listeners // Set the event listeners
client.setSocketEventListeners([ client.setSocketEventListeners([
listenForQueryStatus, listenForQueryStatus,
listenForQueryData, listenForQueryData,
]); ]);
/** /**
* Register resultsList listeners listening to notification events emitted by * Register resultsList listeners listening to notification events emitted by
* the Client class. * the Client class.
*/ */
const listenForClientNotification = new ViewEventListener('notify-view', const listenForClientNotification = new ViewEventListener('notify-view',
recieveClientNotification); recieveClientNotification);
/** /**
* Register vanilla Javascript events to the resultList listening for button * Register vanilla Javascript events to the resultList listening for button
* clicks etc. done by the user. * clicks etc. done by the user.
* Get all needed HTMLElements for those event listeners before. * Get all needed HTMLElements for those event listeners before.
*/ */
resultsList.getHTMLElements([ resultsList.getHTMLElements([
'.add-btn', '.add-btn',
'.pagination', '.pagination',
'#display-options-form-expert_mode', '#display-options-form-expert_mode',
@ -196,28 +201,28 @@ document.addEventListener("DOMContentLoaded", () => {
], ],
'#sub-results-create', '#sub-results-create',
'#sub-results-export', '#sub-results-export',
]); ]);
let args = [resultsList, results, client]; let args = [resultsList, results, client];
const listenForPageNavigation = new ViewEventListener('page-navigation', const listenForPageNavigation = new ViewEventListener('page-navigation',
pageNavigation, pageNavigation,
args); args);
const listenForExpertModeSwitch = new ViewEventListener('expert-mode', const listenForExpertModeSwitch = new ViewEventListener('expert-mode',
expertModeSwitch, expertModeSwitch,
args); args);
const listenForActionButtons = new ViewEventListener('action-buttons', const listenForActionButtons = new ViewEventListener('action-buttons',
actionButtons, actionButtons,
args); args);
const listenForDisplayOptions = new ViewEventListener('display-otions', const listenForDisplayOptions = new ViewEventListener('display-otions',
displayOptions, displayOptions,
args); args);
const listenForShowMetaData = new ViewEventListener('show-meta-data', const listenForShowMetaData = new ViewEventListener('show-meta-data',
showMetaData, showMetaData,
args); args);
const listenForShowCorpusFiles = new ViewEventListener('show-corpus-files', const listenForShowCorpusFiles = new ViewEventListener('show-corpus-files',
showCorpusFiles, showCorpusFiles,
args); args);
// Set and load defined listeners // Set and load defined listeners
resultsList.setViewEventListeners([ resultsList.setViewEventListeners([
listenForClientNotification, listenForClientNotification,
listenForPageNavigation, listenForPageNavigation,
listenForExpertModeSwitch, listenForExpertModeSwitch,
@ -225,17 +230,16 @@ document.addEventListener("DOMContentLoaded", () => {
listenForDisplayOptions, listenForDisplayOptions,
listenForShowMetaData, listenForShowMetaData,
listenForShowCorpusFiles, listenForShowCorpusFiles,
]); ]);
resultsList.loadViewEventListeners(); resultsList.loadViewEventListeners();
// Hide buttons which are not needed when just inspecting results // Hide buttons which are not needed when just inspecting results
resultsList.inspectResultsExport.classList.add('hide'); resultsList.inspectResultsExport.classList.add('hide');
// Execute client event listener callbacks manually because dynamicMode is false // Execute client event listener callbacks manually because dynamicMode is false
client.eventListeners['corpus_analysis_query'].executeCallbacks([resultsJson]); client.eventListeners['corpus_analysis_query'].executeCallbacks([resultsJson]);
// Save meta data to results after the init callback from line above // Save meta data to results after the init callback from line above
results.metaData = metaDataJson; results.metaData = metaDataJson;
client.eventListeners['corpus_analysis_query_results'].executeCallbacks([resultsJson]); client.eventListeners['corpus_analysis_query_results'].executeCallbacks([resultsJson]);
// Enable scroll to Top functionality. // Enable scroll to Top functionality.
scrollToTop('#headline', '#menu-scroll-to-top-div'); scrollToTop('#headline', '#menu-scroll-to-top-div');
});
</script> </script>
{% endblock %} {% endblock %}

@ -1,16 +1,26 @@
{% extends "nopaque.html.j2" %} {% extends "nopaque.html.j2" %}
{% from '_colors.html.j2' import colors %}
{% set scheme_primary_color = colors.corpus_analysis_darken %}
{% set scheme_secondary_color = colors.corpus_analysis %}
{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %}
{% block page_content %} {% block page_content %}
{{ Macros.insert_color_scheme(corpus_analysis_color_darken) }} <div class="container">
<div class="col s12"> <div class="row">
<div class="col s12">
<h1 id="title">{{ title }}</h1>
</div>
<div class="col s12">
<p>Below the metadata for the results from the Corpus <p>Below the metadata for the results from the Corpus
<i>{{ query_result.query_metadata.corpus_name }}</i> generated with the query <i>{{ query_result.query_metadata.corpus_name }}</i> generated with the query
<i>{{ query_result.query_metadata.query }}</i> are shown. <i>{{ query_result.query_metadata.query }}</i> are shown.
</p> </p>
</div>
</div> <div class="col s12">
<div class="col s12">
<div class="card"> <div class="card">
<div class="card-action right-align"> <div class="card-action right-align">
<a class="waves-effect waves-light btn left-align" href="{{ url_for('services.service', service='corpus_analysis') }}">Back To Overview<i class="material-icons right">arrow_back</i></a> <a class="waves-effect waves-light btn left-align" href="{{ url_for('services.service', service='corpus_analysis') }}">Back To Overview<i class="material-icons right">arrow_back</i></a>
@ -69,9 +79,10 @@
<a class="waves-effect waves-light btn" href="{{ url_for('corpora.inspect_query_result', query_result_id=query_result.id) }}">Inspect Results<i class="material-icons right">search</i></a> <a class="waves-effect waves-light btn" href="{{ url_for('corpora.inspect_query_result', query_result_id=query_result.id) }}">Inspect Results<i class="material-icons right">search</i></a>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
<!-- Modal Structure -->
<div id="modal-text-details" class="modal modal-fixed-footer"> <div id="modal-text-details" class="modal modal-fixed-footer">
<div class="modal-content"> <div class="modal-content">
<h4>Bibliographic data</h4> <h4>Bibliographic data</h4>
@ -81,7 +92,10 @@
<a href="#!" class="modal-close waves-effect waves-green red btn">Close</a> <a href="#!" class="modal-close waves-effect waves-green red btn">Close</a>
</div> </div>
</div> </div>
{% endblock page_content %}
{% block scripts %}
{{ super() }}
<script> <script>
var moreTextDetailsButtons; var moreTextDetailsButtons;
moreTextDetailsButtons = document.getElementsByClassName("more-text-detials"); moreTextDetailsButtons = document.getElementsByClassName("more-text-detials");
@ -117,5 +131,4 @@ for (var btn of moreTextDetailsButtons) {
} }
} }
</script> </script>
{% endblock %} {% endblock %}