integrate nopaque repo

This commit is contained in:
Patrick Jentsch
2020-06-05 14:42:04 +02:00
parent 450ddf69fc
commit cb2b64fa9d
164 changed files with 1212 additions and 168 deletions

View File

@ -0,0 +1,29 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12 m4">
<p>Fill out the following form to add a corpus to your corpora.</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">
<div class="card">
<form method="POST">
<div class="card-content">
{{ add_corpus_form.hidden_tag() }}
<div class="row">
<div class="col s12 m4">
{{ M.render_field(add_corpus_form.title, data_length='32', material_icon='title') }}
</div>
<div class="col s12 m8">
{{ M.render_field(add_corpus_form.description, data_length='255', material_icon='description') }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(add_corpus_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,76 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12 m4">
<h3>{{ corpus.title }}</h3>
<p>Fill out the following form to add a corpus file in verticalized text format (.vrt).</p>
<a class="waves-effect waves-light btn" href="{{ url_for('corpora.corpus', corpus_id=corpus.id) }}"><i class="material-icons left">arrow_back</i>Back to corpus</a>
</div>
<div class="col s12 m8">
<form class="nopaque-submit-form" data-progress-modal="progress-modal">
<div class="card">
<div class="card-content">
<span class="card-title">Required metadata</span>
{{ add_corpus_file_form.hidden_tag() }}
<div class="row">
<div class="col s12 m4">
{{ M.render_field(add_corpus_file_form.author, data_length='255', material_icon='person') }}
</div>
<div class="col s12 m4">
{{ M.render_field(add_corpus_file_form.title, data_length='255', material_icon='title') }}
</div>
<div class="col s12 m4">
{{ M.render_field(add_corpus_file_form.publishing_year, material_icon='access_time') }}
</div>
<div class="col s12">
{{ M.render_field(add_corpus_file_form.file, accept='.vrt', placeholder='Choose your .vrt file') }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(add_corpus_file_form.submit, material_icon='send') }}
</div>
</div>
<br>
<ul class="collapsible hoverable">
<li>
<div class="collapsible-header"><i class="material-icons">add</i>Add additional metadata</div>
<div class="collapsible-body">
{% for field in add_corpus_file_form
if field.short_name not in ['author', 'csrf_token', 'file', 'publishing_year', 'submit', 'title'] %}
{{ M.render_field(field, data_length='255', material_icon=field.label.text[0:1]) }}
{% endfor %}
</div>
</li>
</ul>
<br>
<ul class="collapsible hoverable">
<li>
<div class="collapsible-header"><i class="material-icons">add</i>Add metadata with BibTex</div>
<div class="collapsible-body">
<span>
<div class="row">
<div class="col s12">
</div>
</div>
</span>
</div>
</li>
</ul>
</form>
</div>
<div id="progress-modal" class="modal">
<div class="modal-content">
<h4><i class="material-icons prefix">file_upload</i> Uploading file...</h4>
<div class="progress">
<div class="determinate" style="width: 0%"></div>
</div>
</div>
<div class="modal-footer">
<a href="#!" class="modal-close waves-effect waves-light btn red abort-request">Cancel</a>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,477 @@
{% extends "nopaque.html.j2" %}
{% set full_width = True %}
{% block page_content %}
<div class="col s12">
<ul class="collapsible expandable">
<li class="active">
<!-- <div class="collapsible-header">
<i class="material-icons">search</i>CQP Query
</div> -->
<!-- Div element above is part of valid materialize collapsible.
Commented out to prevent the user from collapsing it and also to save
space -->
<div class="collapsible-body" style="padding-top: 10px;
padding-right: 2rem;
padding-bottom: 0px;
padding-left: 2rem;">
<!-- Query form -->
<form id="query-form">
<div class="row">
<div class="col s12 m10">
<div class="input-field">
<i class="material-icons prefix">search</i>
{{ query_form.query() }}
{{ query_form.query.label }}
<span class="helper-text">
<a href="http://cwb.sourceforge.net/files/CQP_Tutorial/">
<i class="material-icons" style="font-size: inherit;">help
</i>
CQP query language tutorial
</a>
</span>
</div>
</div>
<div class="col s12 m2">
<br class="hide-on-small-only">
{{ M.render_field(query_form.submit, material_icon='send') }}
</div>
</div>
</form>
</div>
</li>
<li class="hoverable">
<div class="collapsible-header">
<i class="material-icons">settings</i>Display Options
</div>
<div class="collapsible-body">
<!-- Display options form -->
<form id="display-options-form">
<div class="row">
<div class="col s12 m6">
{{ M.render_field(display_options_form.results_per_page,
material_icon='format_list_numbered') }}
</div>
<div class="col s12 m6">
{{ M.render_field(display_options_form.result_context,
material_icon='short_text') }}
</div>
<div class="col s12">
{{ M.render_field(display_options_form.expert_mode) }}
</div>
</div>
</form>
</div>
</li>
</ul>
</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;">
<span class="card-title">Query Results</span>
<div class="error-container hide show-on-error"></div>
<div class="hide show-on-success">
<div class="col s12 m6 l6">
<div class="row">
<p>
<span id="received-match-count">
</span> of
<span id="match-count"></span>
matches loaded.
<br>
Matches occured in
<span id="text-lookup-count"></span>
corpus files.
</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>
<div class="row">
<div class="progress" id="query-results-progress">
<div class="determinate" id="query-results-determinate"></div>
</div>
</div>
</div>
<div class="col s12 m6 l6">
<div class="row">
<button id="query-results-export"
class="waves-effect
waves-light
btn-small
right disabled"
type="submit">Export Results
<i class="material-icons right">file_download</i>
</button>
</div>
</div>
<!-- Table showing the query results -->
<div class="col s12">
<ul class="pagination paginationTop"></ul>
<table class="responsive-table highlight">
<thead>
<tr>
<th style="width: 2%">Nr.</th>
<th style="width: 3%">Title</th>
<th style="width: 25%">Left context</th>
<th style="width: 45%">Match</th>
<th style="width: 25%">Right Context</th>
</tr>
</thead>
<tbody class="list" id="query-results">
</tbody>
</table>
<ul class="pagination paginationBottom"></ul>
</div>
</div>
</div>
</div>
</div>
<!-- Modals -->
<!-- Analysis init modal -->
<div class="modal no-autoinit" id="init-display">
<div class="modal-content">
<h4>Initializing your corpus analysis session...</h4>
<div class="error-container hide show-on-error"></div>
<div class="hide progress show-while-waiting">
<div class="indeterminate"></div>
</div>
</div>
</div>
<!-- Export query results modal -->
<div id="query-results-download-modal"
class="modal modal-fixed-footer no-autoinit">
<div class="modal-content">
<h4>Download current query Results</h4>
<p>The results of the current query can be downloaded as several files like
csv or json. Those files can be used in other software like Excel.
Also it is easy to publish your results as raw data like this!</p>
<table>
<tr>
<td>JSON</td>
<td>
<a class="btn waves-effect waves-light" id="download-results-json">
Download
<i class="material-icons right">file_download</i>
</a>
</td>
</tr>
<tr>
<td>CSV</td>
<td>
<a class="btn waves-effect waves-light disabled"
id="download-results-csv">
Download
<i class="material-icons right">file_download</i>
</a>
</td>
</tr>
<tr>
<td>EXCEL</td>
<td>
<a class="btn waves-effect waves-light disabled">Download
<i class="material-icons right">file_download</i>
</a>
</td>
</tr>
<tr>
<td>HTML</td>
<td>
<a class="btn waves-effect waves-light disabled">Download
<i class="material-icons right">file_download</i>
</a>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<a href="#!" class="modal-close waves-effect waves-light red btn">Close</a>
</div>
</div>
<!-- Context modal used for detailed information about one match -->
<div id="context-modal" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Match Inspect</h4>
<div id="inspect-display-options">
<form>
<ul class="collection with-header">
<li class="collection-header">
<h5>Display options</h5>
</li>
<li class="collection-item">
{{ inspect_display_options_form.expert_mode_inspect.label.text }}
<div class="secondary-content">
<div class="switch">
<label>
{{ inspect_display_options_form.expert_mode_inspect() }}
<span class="lever"></span>
</label>
</div>
</div>
</li>
<li class="collection-item">
{{ inspect_display_options_form.highlight_sentences.label.text }}
<div class="secondary-content">
<div class="switch">
<label>
{{ inspect_display_options_form.highlight_sentences() }}
<span class="lever"></span>
</label>
</div>
</div>
</li>
<li class="collection-item">
Sentences around match
<div class="secondary-content"
style="margin-top: -35px;
border-top-width: 0px;
margin-bottom: -20px;">
<div class="input-field">
<p class="range-field">
<input type="range"
id="context-sentences"
style="margin-top: 20px;
margin-bottom: 10px;"
min="1"
max="10"
value="3" />
</p>
</div>
</div>
</li>
</ul>
</form>
</div>
<div class="col s12" >
<h5>Context</h5>
<div id="context-results">
</div>
</div>
</div>
<div class="modal-footer">
<a id="inspect-download-context" class="left waves-effect waves-light btn">
Export Context
<i class="material-icons right">file_download</i>
</a>
<a href="#!" class="modal-close waves-effect waves-light red btn">Close</a>
</div>
</div>
<script src="{{ url_for('static', filename='js/nopaque.CorpusAnalysisClient.js') }}">
</script>
<script src="{{ url_for('static', filename='js/nopaque.Results.js') }}">
</script>
<script src="{{ url_for('static', filename='js/nopaque.callbacks.js') }}">
</script>
<script>
// ###### Defining global variables used in other functions ######
var client; // CorpusAnalysisClient first undefined on DOMContentLoaded defined
var collapsibleElements; // All collapsibleElements on this page
var contextModal; // Modal to open on inspect for further match context
var expertModeSwitchElement; // Expert mode switch Element
var initDisplay; // CorpusAnalysisDisplay object first undfined on DOMContentLoaded defined
var matchCountElement; // Total nr. of matches will be displayed in this element
var progress; // global progress value
var queryDisplay; // CorpusAnalysisDisplay object first undfined on DOMContentLoaded defined
var queryFormElement; // the query form
var queryResultsDeterminateElement; // The progress bar for recieved results
var queryResultsExportElement; // Download button opens download modal
var queryResultsProgressElement; // Div element holding the progress bar
var queryResultsUserFeedbackElement; // Element showing match count|total etc
var receivedMatchCountElement; // Nr. of loaded matches will be displayed in this element
var results; // results object
var data; // full JSON object holding match results
var resultsList; // resultsList object
var resultsListOptions; // specifies ResultsList options
var textLookupCountElement // Nr of texts the matches occured in will be shown in this element
// ###### Defining local scope variables ######
let contextPerItemElement; // Form Element for display option
let contextSentencesElement; // Form Element for display option in inspect
let displayOptionsData; // Getting form data from display options
let displayOptionsFormElement; // Form holding the display informations
let downloadResultsJSONElement; // button for downloading results as JSON
let downloadInspectContextElement; // button for downloading inspect context
let exportModal; // Download options modal
let firstPageElement; // first page element of resultsList pagination
let hitsPerPageInputElement;
let initDisplayElement; // Element for initialization using initDisplay
let initModal;
let paginationElements;
let queryDisplayElement; // Element for initialization using queryDisplay
let xpath; // xpath to grab first resultsList page pagination element
// ###### Initialize variables ######
client = undefined;
collapsibleElements = document.querySelector('.collapsible.expandable');
contextModal = document.getElementById("context-modal");
contextSentencesElement = document.getElementById("context-sentences");
displayOptionsFormElement = document.getElementById("display-options-form");
expertModeSwitchElement = document.getElementById("display-options-form-expert_mode");
exportModal = document.getElementById("query-results-download-modal");
initDisplay = undefined;
initDisplayElement = document.getElementById("init-display");
matchCountElement = document.getElementById("match-count");
paginationElements = document.getElementsByClassName("pagination");
queryDisplay = undefined;
queryDisplayElement = document.getElementById("query-display");
queryFormElement = document.getElementById("query-form");
queryResultsDeterminateElement = document.getElementById("query-results-determinate");
queryResultsExportElement = document.getElementById("query-results-export");
queryResultsProgressElement = document.getElementById("query-results-progress");
queryResultsUserFeedbackElement = document.getElementById("query-results-user-feedback");
receivedMatchCountElement = document.getElementById("received-match-count");
textLookupCountElement = document.getElementById("text-lookup-count");
hitsPerPageInputElement = document.getElementById("display-options-form-results_per_page");
contextPerItemElement = document.getElementById("display-options-form-result_context");
// ###### js list options and intialization ######
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>`};
// ###### event on DOMContentLoaded ######
document.addEventListener("DOMContentLoaded", () => {
//set accordion of collapsibles to false
M.Collapsible.init(collapsibleElements, {accordion: false});
// creates some modals on DOMContentLoaded
contextModal = M.Modal.init(contextModal, {"dismissible": true});
exportModal = M.Modal.init(exportModal, {"dismissible": true});
initModal = M.Modal.init(initDisplayElement, {"dismissible": false});
// Init corpus analysis components
data = new Data();
resultsList = new ResultsList("result-list", resultsListOptions);
resultsMetaData = new MetaData();
results = new Results(data, resultsList, resultsMetaData);
initDisplay = new CorpusAnalysisDisplay(initDisplayElement);
queryDisplay = new CorpusAnalysisDisplay(queryDisplayElement);
client = new CorpusAnalysisClient({{ corpus_id }}, nopaque.socket);
initModal.open();
// set displays and callback functions
client.setDisplay("init", initDisplay);
client.setCallback("init", () => {
initModal.close();
});
client.setCallback('get_metadata', () => {
client.getMetaData();
})
client.setCallback('recv_meta_data', (response) => {
recvMetaData(response);
})
client.setDisplay("query", queryResultsUserFeedbackElement);
client.setDisplay("query", queryDisplay);
client.setCallback("query", (payload) => {
querySetup(payload);
});
client.setCallback("query_results", (payload) => {
queryRenderResults(payload);
});
client.setCallback("query_match_context", (payload) => {
results.jsList.showMatchContext(payload);
})
// Trigger corpus analysis initialization on server side
client.init();
// start a query request on submit
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 eg: 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.
firstPageElement;
xpath = '//a[@class="page" and text()=1]';
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.query(results.data.query);
});
// 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;
// eventListener if pagination is used to apply new context size to new page
// and also activate inspect match if progress is 100
for (let element of paginationElements) {
element.addEventListener("click", results.jsList.changeContext);
element.addEventListener("click", results.jsList.activateInspect);
}
expertModeSwitchElement.addEventListener("change", (event) => {
if (event.target.checked) {
results.jsList.expertModeOn("query-display");
for (let element of paginationElements) {
element.onclick = (event) => {
results.jsList.eventHandlerCheck(event)
}
}
} else {
results.jsList.expertModeOff("query-display");
}
});
});
// Add onclick to open download modal when Export Results button is pressed
queryResultsExportElement.onclick = () => {
exportModal.open();
}
// add onclick to download JSON button and download the file
downloadResultsJSONElement = document.getElementById("download-results-json")
downloadResultsJSONElement.onclick = () => {
let filename = results.data.createDownloadFilename("matches");
results.data.addData(results.metaData);
results.data.downloadJSONRessource(filename, results.data,
downloadResultsJSONElement
)};
// add onclick to download JSON button and download the file
downloadInspectContextElement = document.getElementById("inspect-download-context")
downloadInspectContextElement.onclick = () => {
let filename = results.data.createDownloadFilename(`context-id-${results.jsList.contextId}`);
results.data.addData(results.metaData);
results.data.downloadJSONRessource(filename,
results.jsList.contextData,
downloadInspectContextElement);
};
</script>
{% endblock %}

View File

@ -0,0 +1,220 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12 m4">
<h3 id="title">{{ corpus.title }}</h3>
<p id="description">{{ corpus.description }}</p>
<div class="active preloader-wrapper small hide" id="progress-indicator">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
<span class="chip status white-text hide" id="status"></span>
</div>
<div class="col s12 m8">
<div class="card">
<div class="card-content">
<span class="card-title">Chronometrics</span>
<div class="row">
<div class="col s12 m6">
<div class="input-field">
<input disabled value="{{ corpus.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}" id="creation-date" type="text" class="validate">
<label for="creation-date">Creation date</label>
</div>
</div>
<div class="col s12 m6">
<div class="input-field">
<input disabled value="{{ corpus.last_edited_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}" id="last_edited_date" type="text" class="validate">
<label for="creation-date">Last edited</label>
</div>
</div>
<div class="col s12 m6">
<div class="input-field">
<input disabled value="{{ corpus.current_nr_of_tokens }} / {{ corpus.max_nr_of_tokens }}" id="nr_of_tokens" type="text" class="validate">
<label for="creation-date">Nr. of tokens used
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="Current number of tokens in this corpus. Updates after every analyze session.">help</i>
</label>
</div>
</div>
</div>
</div>
<div class="card-action right-align">
<a href="{{ url_for('corpora.analyse_corpus', corpus_id=corpus.id) }}" class="btn disabled hide waves-effect waves-light" id="analyze"><i class="material-icons left">search</i>Analyze</a>
<a href="{{ url_for('corpora.prepare_corpus', corpus_id=corpus.id) }}" class="btn disabled hide waves-effect waves-light" id="build"><i class="material-icons left">build</i>Build</a>
<a data-target="delete-corpus-modal" class="btn modal-trigger red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
</div>
<div class="col s12"></div>
<div class="col s12">
<div class="card">
<div class="card-content" style="overflow: hidden;">
<span class="card-title">Files</span>
<table class="highlight responsive-table">
<thead>
<tr>
<th>Filename</th>
<th>Author</th>
<th>Title</th>
<th>Publishing year</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="show-if-only-child">
<td colspan="5">
<span class="card-title"><i class="material-icons left">book</i>Nothing here...</span>
<p>Corpus is empty. Add texts using the option below.</p>
</td>
</tr>
{% for file in corpus.files %}
<tr>
<td style="word-break: break-word;">{{ file.filename }}</td>
<td style="word-break: break-word;">{{ file.author }}</td>
<td style="word-break: break-word;">{{ file.title }}</td>
<td>{{ file.publishing_year }}</td>
<td class="right-align">
<a class="btn-small waves-effect waves-light" href="{{ url_for('corpora.edit_corpus_file', corpus_file_id=file.id, corpus_id=corpus.id) }}"><i class="material-icons">edit</i></a>
<a class="btn-small waves-effect waves-light" href="{{ url_for('corpora.download_corpus_file', corpus_file_id=file.id, corpus_id=corpus.id) }}"><i class="material-icons">file_download</i></a>
<a data-target="delete-corpus-file-{{ file.id }}-modal" class="btn-small modal-trigger red waves-effect waves-light"><i class="material-icons">delete</i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card-action right-align">
<a href="{{ url_for('corpora.add_corpus_file', corpus_id=corpus.id) }}" class="btn waves-effect waves-light"><i class="material-icons left">add</i>Add corpus file</a>
</div>
</div>
</div>
<!-- Modals -->
<div id="delete-corpus-modal" class="modal">
<div class="modal-content">
<h4>Confirm corpus deletion</h4>
<p>Do you really want to delete the corpus {{corpus.title}}? All files will be permanently deleted!</p>
</div>
<div class="modal-footer">
<a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
<a href="{{ url_for('corpora.delete_corpus', corpus_id=corpus.id) }}" class="btn modal-close red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
{% for file in corpus.files %}
<div id="delete-corpus-file-{{ file.id }}-modal" class="modal">
<div class="modal-content">
<h4>Confirm corpus file deletion</h4>
<p>Do you really want to delete the corpus file {{ file.filename }}? The file will be permanently deleted!</p>
</div>
<div class="modal-footer">
<a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
<a class="btn modal-close red waves-effect waves-light" href="{{ url_for('corpora.delete_corpus_file', corpus_file_id=file.id, corpus_id=corpus.id) }}"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
{% endfor %}
<script>
class InformationUpdater {
constructor(corpusId, foreignCorpusFlag) {
this.corpusId = corpusId;
this.foreignCorpusFlag = foreignCorpusFlag;
if (this.foreignCorpusFlag) {
nopaque.foreignCorporaSubscribers.push(this);
} else {
nopaque.corporaSubscribers.push(this);
}
}
_init() {
let corpus;
corpus = (this.foreignCorpusFlag ? nopaque.foreignUser.corpora[this.corpusId]
: nopaque.user.corpora[this.corpusId]);
// Status
this.setStatus(corpus.status);
}
_update(patch) {
let pathArray;
for (let operation of patch) {
/* "/corpora/{corpusId}/valueName" -> ["{corpusId}", ...] */
pathArray = operation.path.split("/").slice(2);
if (pathArray[0] != this.corpusId) {continue;}
switch(operation.op) {
case "add":
location.reload();
break;
case "delete":
location.reload();
break;
case "replace":
if (pathArray[1] === "status") {
this.setStatus(operation.value);
}
break;
default:
break;
}
}
}
setStatus(status) {
let analyzeElement, buildElement, numFiles, progressIndicatorElement, statusElement;
numFiles = Object.keys((this.foreignCorpusFlag ? nopaque.foreignUser.corpora[this.corpusId] : nopaque.user.corpora[this.corpusId]).files).length;
progressIndicatorElement = document.getElementById("progress-indicator");
if (["queued", "running", "start analysis", "stop analysis"].includes(status)) {
progressIndicatorElement.classList.remove("hide");
} else {
progressIndicatorElement.classList.add("hide");
}
statusElement = document.getElementById("status");
statusElement.dataset.status = status;
statusElement.classList.remove("hide");
analyzeElement = document.getElementById("analyze");
if (["analysing", "prepared", "start analysis"].includes(status)) {
analyzeElement.classList.remove("disabled", "hide");
} else {
analyzeElement.classList.add("disabled", "hide");
}
buildElement = document.getElementById("build");
if (status === "unprepared" && numFiles > 0) {
buildElement.classList.remove("disabled", "hide");
} else {
buildElement.classList.add("disabled", "hide");
}
}
}
{% if corpus.creator == current_user %}
var informationUpdater = new InformationUpdater({{ corpus.id }}, false);
{% else %}
var informationUpdater = new InformationUpdater({{ corpus.id }}, true);
document.addEventListener("DOMContentLoaded", () => {
nopaque.socket.emit("foreign_user_data_stream_init", {{ corpus.user_id }});
});
{% endif %}
</script>
{% endblock %}

View File

@ -0,0 +1,45 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12 m4">
<h3 id="title">...</h3>
<p id="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et</p>
<a class="btn waves-effect waves-light" href="{{ url_for('corpora.corpus', corpus_id=corpus.id) }}"><i class="material-icons left">arrow_back</i>Back to corpus</a>
</div>
<div class="col s12 m8">
<form method="POST">
{{ edit_corpus_file_form.hidden_tag() }}
<div class="card">
<div class="card-content">
<div class="row">
<div class="col s12 m4">
{{ M.render_field(edit_corpus_file_form.author, data_length='255', material_icon='person') }}
</div>
<div class="col s12 m4">
{{ M.render_field(edit_corpus_file_form.title, data_length='255', material_icon='title') }}
</div>
<div class="col s12 m4">
{{ M.render_field(edit_corpus_file_form.publishing_year, material_icon='access_time') }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(edit_corpus_file_form.submit, material_icon='send') }}
</div>
</div>
<br>
<ul class="collapsible hoverable">
<li>
<div class="collapsible-header"><i class="material-icons">edit</i>Edit additional metadata</div>
<div class="collapsible-body">
{% for field in edit_corpus_file_form
if field.short_name not in ['author', 'csrf_token', 'publishing_year', 'submit', 'title'] %}
{{ M.render_field(field) }}
{% endfor %}
</div>
</li>
</ul>
</form>
</div>
{% endblock %}