From ffa7a7812ac12dd9b3b7695637c3d7261ce84e9c Mon Sep 17 00:00:00 2001 From: Patrick Jentsch <pjentsch@sfb1288inf-Notebook.fritz.box> Date: Wed, 28 Oct 2020 16:13:41 +0100 Subject: [PATCH] Rework corpora/query results --- web/app/corpora/views.py | 3 +- .../corpora/interactions/display.html.j2 | 8 +- .../query_results/add_query_result.html.j2 | 53 +-- .../corpora/query_results/inspect.html.j2 | 320 +++++++++--------- .../query_results/query_result.html.j2 | 141 ++++---- 5 files changed, 275 insertions(+), 250 deletions(-) diff --git a/web/app/corpora/views.py b/web/app/corpora/views.py index 1e98b679..309bc3ed 100644 --- a/web/app/corpora/views.py +++ b/web/app/corpora/views.py @@ -51,8 +51,7 @@ def corpus(corpus_id): title=corpus_file.title, publishing_year=corpus_file.publishing_year, corpus_id=corpus.id, - id=corpus_file.id - ) + id=corpus_file.id) for corpus_file in corpus.files] return render_template('corpora/corpus.html.j2', corpus=corpus, diff --git a/web/app/templates/corpora/interactions/display.html.j2 b/web/app/templates/corpora/interactions/display.html.j2 index 1f5c10c0..f6b7b490 100644 --- a/web/app/templates/corpora/interactions/display.html.j2 +++ b/web/app/templates/corpora/interactions/display.html.j2 @@ -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"> <h6 style="margin-top: 0px;">Display</h6> <div class="divider" style="margin-bottom: 10px;"></div> <div class="row"> <div class="col s12"> <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') }} - {{ M.render_field(display_options_form.result_context, + {{ wtf.render_field(display_options_form.result_context, material_icon='short_text') }} <div class="col s12" style="line-height: 38px;"> <div class="col s8"> @@ -27,4 +28,3 @@ </div> </div> </div> - diff --git a/web/app/templates/corpora/query_results/add_query_result.html.j2 b/web/app/templates/corpora/query_results/add_query_result.html.j2 index e2f163fe..3399a97b 100644 --- a/web/app/templates/corpora/query_results/add_query_result.html.j2 +++ b/web/app/templates/corpora/query_results/add_query_result.html.j2 @@ -1,33 +1,42 @@ {% extends "nopaque.html.j2" %} +{% import 'materialize/wtf.html.j2' as wtf %} {% block page_content %} -<div class="col s12 m4"> - <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> -</div> +<div class="container"> + <div class="row"> + <div class="col s12"> + <h1 id="title">{{ title }}</h1> + </div> -<div class="col s12 m8"> - <form class="nopaque-submit-form" data-progress-modal="progress-modal"> - <div class="card"> - <div class="card-content"> - {{ add_query_result_form.hidden_tag() }} - <div class="row"> - <div class="col s12 m4"> - {{ M.render_field(add_query_result_form.title, data_length='32', material_icon='title') }} - </div> - <div class="col s12 m8"> - {{ M.render_field(add_query_result_form.description, data_length='255', material_icon='description') }} + <div class="col s12 m4"> + <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> + </div> + + <div class="col s12 m8"> + <form class="nopaque-submit-form" data-progress-modal="progress-modal"> + <div class="card"> + <div class="card-content"> + {{ add_query_result_form.hidden_tag() }} + <div class="row"> + <div class="col s12 m4"> + {{ wtf.render_field(add_query_result_form.title, data_length='32', material_icon='title') }} + </div> + <div class="col s12 m8"> + {{ wtf.render_field(add_query_result_form.description, data_length='255', material_icon='description') }} + </div> + <div class="col s12"> + {{ wtf.render_field(add_query_result_form.file, accept='.json', placeholder='Choose your .json file') }} + </div> + </div> </div> - <div class="col s12"> - {{ M.render_field(add_query_result_form.file, accept='.json', placeholder='Choose your .json file') }} + <div class="card-action right-align"> + {{ wtf.render_field(add_query_result_form.submit, material_icon='send') }} </div> </div> - </div> - <div class="card-action right-align"> - {{ M.render_field(add_query_result_form.submit, material_icon='send') }} - </div> + </form> </div> - </form> + </div> </div> <div id="progress-modal" class="modal"> diff --git a/web/app/templates/corpora/query_results/inspect.html.j2 b/web/app/templates/corpora/query_results/inspect.html.j2 index 9de1a779..4bcf078b 100644 --- a/web/app/templates/corpora/query_results/inspect.html.j2 +++ b/web/app/templates/corpora/query_results/inspect.html.j2 @@ -1,64 +1,70 @@ {% 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 %} -{{ Macros.insert_color_scheme(corpus_analysis_color_darken) }} -<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 class="row"> + <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> - <div class="col s12 m2 right-align"> - <br class="hide-on-small-only"> - </div> - </form> - </div> + <div class="col s12 m2 right-align"> + <br class="hide-on-small-only"> + </div> + </form> + </div> + </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" id="interactions-menu"> - {% include 'corpora/interactions/infos.html.j2' %} - {% include 'corpora/interactions/display.html.j2' %} - {% include 'corpora/interactions/analysis.html.j2' %} - {% include 'corpora/interactions/cite.html.j2' %} - <div class="hide"> - {# Hide those because they are not needed when inspecting results. - But some of their elements are being asked for by the client. #} - {% include 'corpora/interactions/export.html.j2' %} - {% include 'corpora/interactions/create.html.j2' %} + <!-- 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" id="interactions-menu"> + {% include 'corpora/interactions/infos.html.j2' %} + {% include 'corpora/interactions/display.html.j2' %} + {% include 'corpora/interactions/analysis.html.j2' %} + {% include 'corpora/interactions/cite.html.j2' %} + <div class="hide"> + {# Hide those because they are not needed when inspecting results. + But some of their elements are being asked for by the client. #} + {% include 'corpora/interactions/export.html.j2' %} + {% include 'corpora/interactions/create.html.j2' %} + </div> </div> + {% include 'tables/query_results.html.j2' %} </div> - {% include 'tables/query_results.html.j2' %} </div> </div> </div> -<!-- Scroll to top element --> -{% include 'corpora/interactions/scroll_to_top.html.j2' %} - -<!-- Modals --> +{# Import modals #} {% include 'modals/show_metadata.html.j2' %} {% include 'modals/show_corpus_files.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"> /** * First Phase: @@ -117,125 +123,123 @@ import { * Second Phase: * Asynchronus and event driven code. */ -document.addEventListener("DOMContentLoaded", () => { +/** + * Initializing the results object as a model holding all the data of a + * query. Also holds the metadata of one query and results data. + * After that initialize the ResultsList object as the View handeling the + * representation of the data for the user. + */ +let results = new Results(); +let resultsList = new ResultsList('result-list', ResultsList.options); +// Import results data from json file. +const resultsJson = {{ query_result_file_content|tojson|safe }}; +// Import metadata from DB passed to this view +const metaDataJson = {{ query_metadata|tojson|safe }}; +// Initialize the client with dynamicMode set to false. +const client = new Client({'logging': true, + 'dynamicMode': false, + 'fullContext': metaDataJson.fullContext}); /** - * Initializing the results object as a model holding all the data of a - * query. Also holds the metadata of one query and results data. - * After that initialize the ResultsList object as the View handeling the - * representation of the data for the user. - */ - let results = new Results(); - let resultsList = new ResultsList('result-list', ResultsList.options); - // Import results data from json file. - const resultsJson = {{ query_result_file_content|tojson|safe }}; - // Import metadata from DB passed to this view - const metaDataJson = {{ query_metadata|tojson|safe }}; - // Initialize the client with dynamicMode set to false. - const client = new Client({'logging': true, - 'dynamicMode': false, - 'fullContext': metaDataJson.fullContext}); - /** - * Register needed listeners and their callbacks. But we will - * just call the attached callbacks manually. Because dynamicMode is false. - */ - const listenForQueryStatus = new ClientEventListener('corpus_analysis_query', - recieveQueryStatus); - const queryStatusCallback = new ListenerCallback('corpus_analysis_query', - prepareQueryData, - [client, results]); - listenForQueryStatus.setCallbacks([queryStatusCallback]); - const listenForQueryData = new ClientEventListener('corpus_analysis_query_results', - recieveQueryData); - const queryDataCallback = new ListenerCallback('corpus_analysis_query_results', - saveQueryData, + * Register needed listeners and their callbacks. But we will + * just call the attached callbacks manually. Because dynamicMode is false. + */ +const listenForQueryStatus = new ClientEventListener('corpus_analysis_query', + recieveQueryStatus); +const queryStatusCallback = new ListenerCallback('corpus_analysis_query', + prepareQueryData, [client, results]); - listenForQueryData.setCallbacks([queryDataCallback]); - // Set the event listeners - client.setSocketEventListeners([ - listenForQueryStatus, - listenForQueryData, - ]); - /** - * Register resultsList listeners listening to notification events emitted by - * the Client class. - */ - const listenForClientNotification = new ViewEventListener('notify-view', - recieveClientNotification); - /** - * Register vanilla Javascript events to the resultList listening for button - * clicks etc. done by the user. - * Get all needed HTMLElements for those event listeners before. - */ - resultsList.getHTMLElements([ - '.add-btn', - '.pagination', - '#display-options-form-expert_mode', - '#display-options-form-result_context', - '#display-options-form-results_per_page', - '#full-results-create', - '#full-results-export', - '#inspect-results-export', - '#meta-data-modal-content', - ['#meta-data-modal', { - 'preventScrolling': false, - 'opacity': 0.0, - 'dismissible': false, - 'onOpenEnd': (() => {document.querySelector(".modal-overlay").remove()}) - } - ], - '#query-results-table', - '#show-meta-data', - '#show-corpus-files', - '#show-corpus-files-modal-content', - ['#show-corpus-files-modal', { - 'preventScrolling': false, - 'opacity': 0.0, - 'dismissible': false, - 'onOpenEnd': (() => {document.querySelector(".modal-overlay").remove()}) - } - ], - '#sub-results-create', - '#sub-results-export', - ]); - let args = [resultsList, results, client]; - const listenForPageNavigation = new ViewEventListener('page-navigation', - pageNavigation, - args); - const listenForExpertModeSwitch = new ViewEventListener('expert-mode', - expertModeSwitch, - args); - const listenForActionButtons = new ViewEventListener('action-buttons', - actionButtons, +listenForQueryStatus.setCallbacks([queryStatusCallback]); +const listenForQueryData = new ClientEventListener('corpus_analysis_query_results', + recieveQueryData); +const queryDataCallback = new ListenerCallback('corpus_analysis_query_results', + saveQueryData, + [client, results]); +listenForQueryData.setCallbacks([queryDataCallback]); +// Set the event listeners +client.setSocketEventListeners([ + listenForQueryStatus, + listenForQueryData, +]); +/** + * Register resultsList listeners listening to notification events emitted by + * the Client class. + */ +const listenForClientNotification = new ViewEventListener('notify-view', + recieveClientNotification); +/** + * Register vanilla Javascript events to the resultList listening for button + * clicks etc. done by the user. + * Get all needed HTMLElements for those event listeners before. + */ +resultsList.getHTMLElements([ + '.add-btn', + '.pagination', + '#display-options-form-expert_mode', + '#display-options-form-result_context', + '#display-options-form-results_per_page', + '#full-results-create', + '#full-results-export', + '#inspect-results-export', + '#meta-data-modal-content', + ['#meta-data-modal', { + 'preventScrolling': false, + 'opacity': 0.0, + 'dismissible': false, + 'onOpenEnd': (() => {document.querySelector(".modal-overlay").remove()}) + } + ], + '#query-results-table', + '#show-meta-data', + '#show-corpus-files', + '#show-corpus-files-modal-content', + ['#show-corpus-files-modal', { + 'preventScrolling': false, + 'opacity': 0.0, + 'dismissible': false, + 'onOpenEnd': (() => {document.querySelector(".modal-overlay").remove()}) + } + ], + '#sub-results-create', + '#sub-results-export', +]); +let args = [resultsList, results, client]; +const listenForPageNavigation = new ViewEventListener('page-navigation', + pageNavigation, + args); +const listenForExpertModeSwitch = new ViewEventListener('expert-mode', + expertModeSwitch, + args); +const listenForActionButtons = new ViewEventListener('action-buttons', + actionButtons, + args); +const listenForDisplayOptions = new ViewEventListener('display-otions', + displayOptions, + args); +const listenForShowMetaData = new ViewEventListener('show-meta-data', + showMetaData, + args); +const listenForShowCorpusFiles = new ViewEventListener('show-corpus-files', + showCorpusFiles, args); - const listenForDisplayOptions = new ViewEventListener('display-otions', - displayOptions, - args); - const listenForShowMetaData = new ViewEventListener('show-meta-data', - showMetaData, - args); - const listenForShowCorpusFiles = new ViewEventListener('show-corpus-files', - showCorpusFiles, - args); - // Set and load defined listeners - resultsList.setViewEventListeners([ - listenForClientNotification, - listenForPageNavigation, - listenForExpertModeSwitch, - listenForActionButtons, - listenForDisplayOptions, - listenForShowMetaData, - listenForShowCorpusFiles, - ]); - resultsList.loadViewEventListeners(); - // Hide buttons which are not needed when just inspecting results - resultsList.inspectResultsExport.classList.add('hide'); - // Execute client event listener callbacks manually because dynamicMode is false - client.eventListeners['corpus_analysis_query'].executeCallbacks([resultsJson]); - // Save meta data to results after the init callback from line above - results.metaData = metaDataJson; - client.eventListeners['corpus_analysis_query_results'].executeCallbacks([resultsJson]); - // Enable scroll to Top functionality. - scrollToTop('#headline', '#menu-scroll-to-top-div'); -}); +// Set and load defined listeners +resultsList.setViewEventListeners([ + listenForClientNotification, + listenForPageNavigation, + listenForExpertModeSwitch, + listenForActionButtons, + listenForDisplayOptions, + listenForShowMetaData, + listenForShowCorpusFiles, +]); +resultsList.loadViewEventListeners(); +// Hide buttons which are not needed when just inspecting results +resultsList.inspectResultsExport.classList.add('hide'); +// Execute client event listener callbacks manually because dynamicMode is false +client.eventListeners['corpus_analysis_query'].executeCallbacks([resultsJson]); +// Save meta data to results after the init callback from line above +results.metaData = metaDataJson; +client.eventListeners['corpus_analysis_query_results'].executeCallbacks([resultsJson]); +// Enable scroll to Top functionality. +scrollToTop('#headline', '#menu-scroll-to-top-div'); </script> {% endblock %} diff --git a/web/app/templates/corpora/query_results/query_result.html.j2 b/web/app/templates/corpora/query_results/query_result.html.j2 index 95ba18ca..5936d9a4 100644 --- a/web/app/templates/corpora/query_results/query_result.html.j2 +++ b/web/app/templates/corpora/query_results/query_result.html.j2 @@ -1,77 +1,88 @@ {% extends "nopaque.html.j2" %} +{% from '_colors.html.j2' import colors %} -{% block page_content %} -{{ Macros.insert_color_scheme(corpus_analysis_color_darken) }} -<div class="col s12"> - <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.query }}</i> are shown. - </p> +{% set scheme_primary_color = colors.corpus_analysis_darken %} +{% set scheme_secondary_color = colors.corpus_analysis %} -</div> +{% block main_attribs %} class="corpus-analysis-color lighten"{% endblock main_attribs %} -<div class="col s12"> - <div class="card"> - <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" href="{{ url_for('corpora.inspect_query_result', query_result_id=query_result.id) }}">Inspect Results<i class="material-icons right">search</i></a> +{% block page_content %} +<div class="container"> + <div class="row"> + <div class="col s12"> + <h1 id="title">{{ title }}</h1> </div> - <div class="card-content" id="results"> - <table class="responsive-table highlight"> - <thead> - <tr> - <th>Metadata Description</th> - <th>Value</th> - </tr> - </thead> - <tbody> - {% for pair in query_result.query_metadata|dictsort %} - <tr> - <td>{{ pair[0] }}</td> - {% if pair[0] == 'corpus_all_texts' - or pair[0] == 'text_lookup' %} - <td> - <table> - {% for key, value in pair[1].items() %} - <tr style="border-bottom: none;"> - <td> - <i>{{ value['title'] }}</i> written - by <i>{{ value['author'] }}</i> - in <i>{{ value['publishing_year'] }}</i> - <a class="waves-effect - waves-light - btn - right - more-text-detials" - data-metadata-key="{{ pair[0] }}" - data-text-key="{{ key }}">More - <i class="material-icons right" + + <div class="col s12"> + <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.query }}</i> are shown. + </p> + </div> + + <div class="col s12"> + <div class="card"> + <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" 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 class="card-content" id="results"> + <table class="responsive-table highlight"> + <thead> + <tr> + <th>Metadata Description</th> + <th>Value</th> + </tr> + </thead> + <tbody> + {% for pair in query_result.query_metadata|dictsort %} + <tr> + <td>{{ pair[0] }}</td> + {% if pair[0] == 'corpus_all_texts' + or pair[0] == 'text_lookup' %} + <td> + <table> + {% for key, value in pair[1].items() %} + <tr style="border-bottom: none;"> + <td> + <i>{{ value['title'] }}</i> written + by <i>{{ value['author'] }}</i> + in <i>{{ value['publishing_year'] }}</i> + <a class="waves-effect + waves-light + btn + right + more-text-detials" data-metadata-key="{{ pair[0] }}" - data-text-key="{{ key }}"> - info_outline - </i> - </a> - </td> - </tr> + data-text-key="{{ key }}">More + <i class="material-icons right" + data-metadata-key="{{ pair[0] }}" + data-text-key="{{ key }}"> + info_outline + </i> + </a> + </td> + </tr> + {% endfor %} + </table> + </td> + {% else %} + <td>{{ pair[1] }}</td> + {% endif %} + </tr> {% endfor %} - </table> - </td> - {% else %} - <td>{{ pair[1] }}</td> - {% endif %} - </tr> - {% endfor %} - </tbody> - </table> - </div> - <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" href="{{ url_for('corpora.inspect_query_result', query_result_id=query_result.id) }}">Inspect Results<i class="material-icons right">search</i></a> + </tbody> + </table> + </div> + <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" 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> -<!-- Modal Structure --> <div id="modal-text-details" class="modal modal-fixed-footer"> <div class="modal-content"> <h4>Bibliographic data</h4> @@ -81,7 +92,10 @@ <a href="#!" class="modal-close waves-effect waves-green red btn">Close</a> </div> </div> +{% endblock page_content %} +{% block scripts %} +{{ super() }} <script> var moreTextDetailsButtons; moreTextDetailsButtons = document.getElementsByClassName("more-text-detials"); @@ -117,5 +131,4 @@ for (var btn of moreTextDetailsButtons) { } } </script> - {% endblock %} -- GitLab