mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-01-18 14:00:33 +00:00
Add show corpus metadata function to result inspect.
This commit is contained in:
parent
0b4e151bef
commit
1bb265b7f4
@ -792,8 +792,22 @@ class ResultsList extends List {
|
||||
</thead>
|
||||
<tbody>`
|
||||
for (let [outerKey, outerValue] of Object.entries(metaDataObject)) {
|
||||
html += `<tr>
|
||||
<td style="text-transform: uppercase;">${outerKey.replace(/_/g, " ")}</td>`
|
||||
// Use more descriptive names
|
||||
if (outerKey === 'corpus_all_texts') {
|
||||
let tmpName = 'All texts in this corpus';
|
||||
html += `<tr>
|
||||
<td style="text-transform: uppercase;">${tmpName.replace(/_/g, " ")}
|
||||
</td>`
|
||||
} else if (outerKey === 'text_lookup') {
|
||||
let tmpName = 'Texts where the query resulted in matches'
|
||||
html += `<tr>
|
||||
<td style="text-transform: uppercase;">${tmpName.replace(/_/g, " ")}
|
||||
</td>`
|
||||
} else {
|
||||
html += `<tr>
|
||||
<td style="text-transform: uppercase;">${outerKey.replace(/_/g, " ")}
|
||||
</td>`
|
||||
}
|
||||
if (outerKey === "corpus_all_texts" || outerKey === "text_lookup") {
|
||||
html += `<td>
|
||||
<ul class="collapsible">`
|
||||
|
@ -59,7 +59,6 @@
|
||||
|
||||
<!-- Modals -->
|
||||
{% include 'modals/show_metadata.html.j2' %}
|
||||
{% include 'modals/show_text_details.html.j2' %}
|
||||
{% include 'modals/analysis_init.html.j2' %}
|
||||
{% include 'modals/export_query_results.html.j2' %}
|
||||
{% include 'modals/context_modal.html.j2' %}
|
||||
@ -187,7 +186,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
listenForMetaData,
|
||||
listenForViewNotification,
|
||||
listenForResults]);
|
||||
console.log(client.eventListeners);
|
||||
// Load the listeners so that they will be executed if triggered
|
||||
client.loadSocketEventListeners();
|
||||
/**
|
||||
|
@ -1,4 +1,3 @@
|
||||
<!-- Scroll to top element -->
|
||||
<div id="menu-scroll-to-top-div" class="fixed-action-btn direction-top active hide" style="bottom: 45px; right: 24px;">
|
||||
<a id="menu-scroll-to-top" class="btn btn-floating btn-large cyan">
|
||||
<i class="material-icons">arrow_upward</i>
|
||||
|
@ -7,14 +7,8 @@ results -->
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn red">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
{% if query_metadata is defined %}
|
||||
<div class="modal-content">
|
||||
{{ Macros.show_metadata(query_metadata) }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="modal-content" id="meta-data-modal-content">
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn red">Close</a>
|
||||
</div>
|
||||
|
@ -40,6 +40,7 @@
|
||||
{% include 'interactions/analysis.html.j2' %}
|
||||
{% include 'interactions/cite.html.j2' %}
|
||||
<div class="hide">
|
||||
{# Hide those because they are not needed when inspecting results #}
|
||||
{% include 'interactions/export.html.j2' %}
|
||||
{% include 'interactions/create.html.j2' %}
|
||||
</div>
|
||||
@ -54,7 +55,6 @@
|
||||
|
||||
<!-- Modals -->
|
||||
{% include 'modals/show_metadata.html.j2' %}
|
||||
{% include 'modals/show_text_details.html.j2' %}
|
||||
{% include 'modals/context_modal.html.j2' %}
|
||||
|
||||
|
||||
@ -122,7 +122,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
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 }};
|
||||
/**
|
||||
* Register needed listeners and their callbacks. But we will
|
||||
* just call the attached callbacks manually. Because dynamicMode is false.
|
||||
*/
|
||||
@ -159,14 +161,19 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
'#display-options-form-result_context',
|
||||
'#display-options-form-results_per_page',
|
||||
'#full-results-create',
|
||||
'#inspect-results-export',
|
||||
'#meta-data-modal-content',
|
||||
'#meta-data-modal',
|
||||
'#query-results-table',
|
||||
'#show-meta-data',
|
||||
'#sub-results-create',
|
||||
]);
|
||||
// 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])
|
||||
/**
|
||||
* The following listener handles what functions are called when the user
|
||||
|
@ -1,233 +0,0 @@
|
||||
{% 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 %}
|
@ -35,78 +35,3 @@
|
||||
main .tabs .indicator {background-color: {{ hex_color }};}
|
||||
</style>
|
||||
{%- endmacro -%}
|
||||
|
||||
{% macro show_metadata(query_metadata) %}
|
||||
|
||||
<div class="col s12">
|
||||
<table class="highlight">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 33%">Metadata Description</th>
|
||||
<th style="width: 66%">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for pair in query_metadata|dictsort %}
|
||||
<tr>
|
||||
<td>{{ pair[0]|replace("_", " ")|upper() }}</td>
|
||||
{% if pair[0] == "corpus_all_texts"
|
||||
or pair[0] == "text_lookup" %}
|
||||
<td>
|
||||
<ul class="collapsible">
|
||||
{% for key, value in pair[1].items() %}
|
||||
<li class="text-metadata"
|
||||
data-metadata-key="{{ pair[0] }}"
|
||||
data-text-key="{{ key }}">
|
||||
<div class="collapsible-header"
|
||||
data-metadata-key="{{ pair[0] }}"
|
||||
data-text-key="{{ key }}">
|
||||
<i class="material-icons"
|
||||
data-metadata-key="{{ pair[0] }}"
|
||||
data-text-key="{{ key }}">info_outline</i>
|
||||
{{ value['author'] }} - {{ value['publishing_year'] }}
|
||||
- {{ value['title'] }}
|
||||
</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<ul id="bibliographic-data-{{ pair[0] }}-{{ key }}"
|
||||
style="column-count: 2;">
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ pair[1] }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
let elems = document.querySelectorAll('.collapsible');
|
||||
let instances = M.Collapsible.init(elems, {accordion: false});
|
||||
});
|
||||
let collapsibles = document.getElementsByClassName("text-metadata");
|
||||
for (let collapsible of collapsibles) {
|
||||
collapsible.onclick = () => {
|
||||
let metadataKey = event.target.dataset.metadataKey;
|
||||
let textKey = event.target.dataset.textKey;
|
||||
let textData = {{ query_metadata|tojson|safe }}[metadataKey][textKey];
|
||||
let bibliographicData = document.getElementById(`bibliographic-data-${metadataKey}-${textKey}`);
|
||||
bibliographicData.innerHTML = "";
|
||||
for (let [key, value] of Object.entries(textData)) {
|
||||
bibliographicData.insertAdjacentHTML("afterbegin",
|
||||
`
|
||||
<li><span style="text-transform: capitalize;">${key}:</span> ${value}</li>
|
||||
`);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endmacro %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user