mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-06-12 09:00:40 +00:00
Merge branch 'development' of gitlab.ub.uni-bielefeld.de:sfb1288inf/opaque into development
This commit is contained in:
@ -1,28 +0,0 @@
|
||||
{% extends "full_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">User list</span>
|
||||
<div id="users">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-corpus" class="search" type="text"></input>
|
||||
<label for="search-corpus">Search users</label>
|
||||
</div>
|
||||
{{ table }}
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var options = {
|
||||
valueNames: ['username', 'email', 'role', 'confirmed', 'id'],
|
||||
page: 10,
|
||||
pagination: true
|
||||
};
|
||||
var userList = new List('users', options);
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,104 +0,0 @@
|
||||
{% extends "limited_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12 m6">
|
||||
<div class="card large">
|
||||
<div class="card-content">
|
||||
<span class="card-title">User information</span>
|
||||
<ul>
|
||||
<li>Username: {{selected_user.username}}</li>
|
||||
<li>Email: {{selected_user.email}}</li>
|
||||
<li>ID: {{selected_user.id}}</li>
|
||||
<li>Registration date: {{registration_date}}</li>
|
||||
<li>Confirmed status: {{selected_user.confirmed}}</li>
|
||||
<li>Role ID: {{selected_user.role_id}}</li>
|
||||
<li>Permissions as Int: {{selected_user.role.permissions}}</li>
|
||||
<li>Role name: {{selected_user.role.name}}</li>
|
||||
</ul>
|
||||
<div class="card-action">
|
||||
<a href="{{url_for('admin.edit_profile_admin', user_id=selected_user.id)}}" class="waves-effect waves-light btn"><i class="material-icons left">edit</i>Edit user</a>
|
||||
<a href="#modal-confirm-delete" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete User</a>
|
||||
<!-- Modal Strucutre -->
|
||||
<div id="modal-confirm-delete" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Confirm deletion</h4>
|
||||
<p>Do you really want to delete the current selected user ({{selected_user.username}})?
|
||||
All associated jobs and job files will be permanently deleted.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="{{url_for('admin.admin_delete_user', user_id=selected_user.id)}}" class="modal-close waves-effect waves-green btn red"><i class="material-icons left">delete</i>Delete User</a>
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn cancel">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
socket.emit('subscribe_foreign_user_ressources', {{ selected_user.id }});
|
||||
</script>
|
||||
<div class="col s12 m6">
|
||||
<div id="job-foreign-list">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">User Jobs</span>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-job" class="search" type="text"></input>
|
||||
<label for="search-job">Search job</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var jobList = new JobList("job-foreign-list", foreignJobsSubscribers, {
|
||||
item: '<div><span class="title"></span><span class="description"></span></div>',
|
||||
page: 4,
|
||||
pagination: true,
|
||||
valueNames: ["description", "title", {data: ["id"]}]
|
||||
});
|
||||
jobList.on("filterComplete", List.updatePagination);
|
||||
jobList.on("searchComplete", List.updatePagination);
|
||||
</script>
|
||||
<div class="col s12 m6">
|
||||
<div id="corpus-foreign-list">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">User Corpora</span>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-job" class="search" type="text"></input>
|
||||
<label for="search-job">Search corpus</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var corpusList = new CorpusList("corpus-foreign-list", foreignCorporaSubscribers, {
|
||||
item: '<div><span class="title"></span><span class="description"></span></div>',
|
||||
page: 4,
|
||||
pagination: true,
|
||||
valueNames: ["description", "title", {data: ["id"]}]
|
||||
});
|
||||
corpusList.on("filterComplete", List.updatePagination);
|
||||
corpusList.on("searchComplete", List.updatePagination);
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,59 +0,0 @@
|
||||
{% extends "limited_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="input-field ">
|
||||
<i class="material-icons prefix">account_circle</i>
|
||||
{{ form.username() }}
|
||||
{{ form.username.label }}
|
||||
{% for error in form.username.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">mail</i>
|
||||
{{ form.email() }}
|
||||
{{ form.email.label }}
|
||||
{% for error in form.email.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">swap_vert</i>
|
||||
{{ form.role() }}
|
||||
{{ form.role.label }}
|
||||
{% for error in form.role.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="switch">
|
||||
<i class="material-icons prefix">check</i>
|
||||
<label class="active" for="{{form.confirmed.name}}">
|
||||
Confirmed status:
|
||||
Off
|
||||
{% if form.confirmed.data == True %}
|
||||
<input type="checkbox" id="{{form.confirmed.name}}" name="{{form.confirmed.name}}" checked="checked">
|
||||
{% else %}
|
||||
<input type="checkbox" id="{{form.confirmed.name}}" name="{{form.confirmed.name}}">
|
||||
{% endif %}
|
||||
<span class="lever"></span>
|
||||
On
|
||||
</label>
|
||||
{% for error in form.confirmed.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ form.submit(class='btn') }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
64
app/templates/admin/edit_user.html.j2
Normal file
64
app/templates/admin/edit_user.html.j2
Normal file
@ -0,0 +1,64 @@
|
||||
{% extends "limited_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12 m4">
|
||||
<h3 id="title">{{ user.username }}</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 justo duo dolores et ea rebum. Stet clita kasd gubergren,</p>
|
||||
<a class="waves-effect waves-light btn" href="{{ url_for('admin.user', user_id=user.id) }}"><i class="material-icons left">arrow_back</i>Back to user administration</a>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
{{ edit_user_form.hidden_tag() }}
|
||||
<div class="input-field ">
|
||||
<i class="material-icons prefix">account_circle</i>
|
||||
{{ edit_user_form.username() }}
|
||||
{{ edit_user_form.username.label }}
|
||||
{% for error in edit_user_form.username.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">mail</i>
|
||||
{{ edit_user_form.email() }}
|
||||
{{ edit_user_form.email.label }}
|
||||
{% for error in edit_user_form.email.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">swap_vert</i>
|
||||
{{ edit_user_form.role() }}
|
||||
{{ edit_user_form.role.label }}
|
||||
{% for error in edit_user_form.role.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="switch">
|
||||
<i class="material-icons prefix">check</i>
|
||||
<label class="active" for="{{ edit_user_form.confirmed.name }}">
|
||||
Confirmed status:
|
||||
Off
|
||||
{% if edit_user_form.confirmed.data == True %}
|
||||
<input type="checkbox" id="{{ edit_user_form.confirmed.name }}" name="{{ edit_user_form.confirmed.name }}" checked="checked">
|
||||
{% else %}
|
||||
<input type="checkbox" id="{{ edit_user_form.confirmed.name }}" name="{{ edit_user_form.confirmed.name }}">
|
||||
{% endif %}
|
||||
<span class="lever"></span>
|
||||
On
|
||||
</label>
|
||||
{% for error in edit_user_form.confirmed.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<button class="btn waves-effect waves-light" id="submit" name="submit" type="submit">Submit<i class="material-icons right">send</i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
26
app/templates/admin/index.html.j2
Normal file
26
app/templates/admin/index.html.j2
Normal file
@ -0,0 +1,26 @@
|
||||
{% extends "full_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12">
|
||||
<div id="user-list">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">User list</span>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-user" class="search" type="text"></input>
|
||||
<label for="search-user">Search user</label>
|
||||
</div>
|
||||
{{ table }}
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var options = {page: 10, pagination: true,
|
||||
valueNames: ['username', 'email', 'role', 'confirmed', 'id']};
|
||||
var userList = new List('user-list', options);
|
||||
</script>
|
||||
{% endblock %}
|
115
app/templates/admin/user.html.j2
Normal file
115
app/templates/admin/user.html.j2
Normal file
@ -0,0 +1,115 @@
|
||||
{% extends "limited_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12 m4">
|
||||
<h3 id="title">{{ user.username }}</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 justo duo dolores et ea rebum. Stet clita kasd gubergren,</p>
|
||||
<a class="waves-effect waves-light btn" href="{{ url_for('admin.index') }}"><i class="material-icons left">arrow_back</i>Back to admin board</a>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">User information</span>
|
||||
<ul>
|
||||
<li>Username: {{ user.username }}</li>
|
||||
<li>Email: {{ user.email }}</li>
|
||||
<li>ID: {{ user.id }}</li>
|
||||
<li>Registration date: {{ user.registration_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}</li>
|
||||
<li>Confirmed status: {{ user.confirmed }}</li>
|
||||
<li>Role ID: {{ user.role_id }}</li>
|
||||
<li>Permissions as Int: {{ user.role.permissions }}</li>
|
||||
<li>Role name: {{ user.role.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a href="{{ url_for('admin.edit_user', user_id=user.id) }}" class="waves-effect waves-light btn"><i class="material-icons left">edit</i>Edit user</a>
|
||||
<a data-target="delete-user-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete user</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12"></div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div id="corpus-list">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Corpora</span>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-corpus" class="search" type="text"></input>
|
||||
<label for="search-corpus">Search corpus</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div id="job-list">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Jobs</span>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-job" class="search" type="text"></input>
|
||||
<label for="search-job">Search job</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modals -->
|
||||
<div id="delete-user-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Confirm user deletion</h4>
|
||||
<p>Do you really want to delete the user {{ user.username }}? All associated data will be permanently deleted!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn cancel">Cancel</a>
|
||||
<a href="{{ url_for('admin.delete_user', user_id=user.id) }}" class="modal-close waves-effect waves-green btn red">Confirm<i class="material-icons right">send</i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
socket.emit('subscribe_foreign_user_ressources', {{ user.id }});
|
||||
|
||||
var corpusList = new CorpusList("corpus-list", foreignCorporaSubscribers, {
|
||||
item: '<div><span class="title"></span><span class="description"></span></div>',
|
||||
page: 4,
|
||||
pagination: true,
|
||||
valueNames: ["description", "title", {data: ["id"]}]
|
||||
});
|
||||
corpusList.on("filterComplete", List.updatePagination);
|
||||
corpusList.on("searchComplete", List.updatePagination);
|
||||
|
||||
var jobList = new JobList("job-list", foreignJobsSubscribers, {
|
||||
item: '<div><span class="title"></span><span class="description"></span></div>',
|
||||
page: 4,
|
||||
pagination: true,
|
||||
valueNames: ["description", "title", {data: ["id"]}]
|
||||
});
|
||||
jobList.on("filterComplete", List.updatePagination);
|
||||
jobList.on("searchComplete", List.updatePagination);
|
||||
</script>
|
||||
{% endblock %}
|
@ -37,7 +37,6 @@
|
||||
var jobsSubscribers = [];
|
||||
var socket = io();
|
||||
|
||||
socket.emit('subscribe_user_ressources');
|
||||
socket.on('init-corpora', function(msg) {
|
||||
corpora = JSON.parse(msg);
|
||||
for (let subscriber of corporaSubscribers) {subscriber._init(corpora);}
|
||||
@ -141,7 +140,7 @@
|
||||
{% if current_user.is_administrator() %}
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">Administration</a></li>
|
||||
<li><a href="{{ url_for('admin.for_admins_only') }}"><i class="material-icons">build</i>Administration tools</a></li>
|
||||
<li><a href="{{ url_for('admin.index') }}"><i class="material-icons">build</i>Administration tools</a></li>
|
||||
{% endif %}
|
||||
<div class="hide-on-large-only">
|
||||
<li><div class="divider"></div></li>
|
||||
@ -170,28 +169,31 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
|
||||
<script>
|
||||
M.AutoInit();
|
||||
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="text"]'))
|
||||
M.Dropdown.init(
|
||||
document.getElementById("nav-notifications"),
|
||||
{"alignment": "right", "constrainWidth": false, "coverTrigger": false}
|
||||
);
|
||||
M.Dropdown.init(
|
||||
document.getElementById("nav-account"),
|
||||
{"alignment": "right", "constrainWidth": false, "coverTrigger": false}
|
||||
);
|
||||
// Highlight current navigation entry
|
||||
var entry;
|
||||
for (entry of document.querySelectorAll("#slide-out a:not(.subheader)")) {
|
||||
if (entry.href === window.location.href) {
|
||||
entry.parentNode.classList.add("active");
|
||||
}
|
||||
socket.emit('subscribe_user_ressources');
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
|
||||
<script>
|
||||
M.AutoInit();
|
||||
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="text"]'))
|
||||
M.Dropdown.init(
|
||||
document.getElementById("nav-notifications"),
|
||||
{"alignment": "right", "constrainWidth": false, "coverTrigger": false}
|
||||
);
|
||||
M.Dropdown.init(
|
||||
document.getElementById("nav-account"),
|
||||
{"alignment": "right", "constrainWidth": false, "coverTrigger": false}
|
||||
);
|
||||
// Highlight current navigation entry
|
||||
var entry;
|
||||
for (entry of document.querySelectorAll("#slide-out a:not(.subheader)")) {
|
||||
if (entry.href === window.location.href) {
|
||||
entry.parentNode.classList.add("active");
|
||||
}
|
||||
{% for message in get_flashed_messages() %}
|
||||
M.toast({html: '{{ message }}'})
|
||||
{% endfor %}
|
||||
}
|
||||
{% for message in get_flashed_messages() %}
|
||||
M.toast({html: '{{ message }}'})
|
||||
{% endfor %}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
125
app/templates/corpora/analyse_corpus.html.j2
Normal file
125
app/templates/corpora/analyse_corpus.html.j2
Normal file
@ -0,0 +1,125 @@
|
||||
{% extends "full_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="col s12 m3 sticky">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<form id="query-form" method="POST">
|
||||
{{ query_form.hidden_tag() }}
|
||||
<span class="card-title">Query and analysis</span>
|
||||
<div class="input-field">
|
||||
{{ query_form.query(class='materialize-textarea') }}
|
||||
{{ query_form.query.label }}
|
||||
{% for error in query_form.query.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button class="btn waves-effect waves-light" id="query-form-submit" style="width: 100%;" type="submit">Start Query</button>
|
||||
<p> </p>
|
||||
<span class="card-title">Help</span>
|
||||
<p><a href="http://cwb.sourceforge.net/files/CQP_Tutorial/">CQP Query Language Tutorial</a></p>
|
||||
<p> </p>
|
||||
<span class="card-title">Options</span>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">format_list_numbered</i>
|
||||
{{ query_form.hits_per_page() }}
|
||||
{{ query_form.hits_per_page.label }}
|
||||
{% for error in query_form.hits_per_page.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">short_text</i>
|
||||
{{ query_form.context() }}
|
||||
{{ query_form.context.label }}
|
||||
{% for error in query_form.context.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<form id="download-form" method="POST">
|
||||
{{ query_download_form.hidden_tag() }}
|
||||
<span class="card-title">Download Results</span>
|
||||
<p>Downlaod all results of the current query as csv, excel or json file.</p>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">insert_drive_file</i>
|
||||
{{ query_download_form.file_type() }}
|
||||
{{ query_download_form.file_type.label }}
|
||||
{% for error in query_download_form.file_type.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button class="btn waves-effect waves-light" id="download-form-submit" style="width: 100%;" type="submit">Download</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m9">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Query Results</span>
|
||||
<div id="query-results"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading-modal" class="modal no-autoinit">
|
||||
<div class="modal-content">
|
||||
<h4>Waiting for analysis software</h4>
|
||||
<div class="preloader-wrapper big active">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var loadingModal;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
loadingModal = M.Modal.init(document.getElementById("loading-modal"),
|
||||
{"dismissible": false});
|
||||
loadingModal.open();
|
||||
});
|
||||
socket.emit('init_corpus_analysis', {{ corpus_id }});
|
||||
|
||||
var queryFormElement = document.getElementById("query-form");
|
||||
var queryFormSubmitElement = document.getElementById("query-form-submit");
|
||||
var queryResultsElement = document.getElementById("query-results");
|
||||
|
||||
queryFormSubmitElement.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
let formData = new FormData(queryFormElement);
|
||||
let queryData = {'context': formData.get('context'),
|
||||
'hits_per_page': formData.get('hits_per_page'),
|
||||
'query': formData.get('query')};
|
||||
socket.emit('query', queryData);
|
||||
M.toast({html: 'Query has been sent!'});
|
||||
});
|
||||
|
||||
socket.on('init_corpus_analysis', function(msg) {
|
||||
if (msg === 'Ready') {loadingModal.close();}
|
||||
});
|
||||
socket.on('query', function(results) {
|
||||
queryResultsElement.innerHTML = '';
|
||||
for (let result of results) {
|
||||
queryResultsElement.innerHTML += '<p>' + result['word_list'] + '</p>';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,83 +1,6 @@
|
||||
{% extends "limited_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<script>
|
||||
{% if corpus.creator == current_user %}
|
||||
var foreignCorpusFlag = false;
|
||||
{% else %}
|
||||
var foreignCorpusFlag = true;
|
||||
socket.emit('subscribe_foreign_user_ressources', {{ corpus.user_id }});
|
||||
{% endif %}
|
||||
|
||||
class InformationUpdater {
|
||||
constructor(corpusId) {
|
||||
this.corpusId = corpusId;
|
||||
if (foreignCorpusFlag) {
|
||||
foreignCorporaSubscribers.push(this);
|
||||
} else {
|
||||
corporaSubscribers.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
_init() {
|
||||
if (foreignCorpusFlag) {
|
||||
this.corpus = foreignCorpora[this.corpusId];
|
||||
} else {
|
||||
this.corpus = corpora[this.corpusId];
|
||||
}
|
||||
|
||||
// Status
|
||||
this.setStatus(this.corpus.status);
|
||||
}
|
||||
|
||||
_update(patch) {
|
||||
var pathArray;
|
||||
|
||||
for (let operation of patch) {
|
||||
/* "/corpusId/valueName" -> ["corpusId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
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) {
|
||||
var statusElement;
|
||||
statusElement = document.getElementById("status");
|
||||
statusElement.classList.remove(...Object.values(CorpusList.STATUS_COLORS));
|
||||
statusElement.classList.add(CorpusList.STATUS_COLORS[status] || CorpusList.STATUS_COLORS['default']);
|
||||
statusElement.innerText = status;
|
||||
var analyseBtn = document.getElementById('analyse');
|
||||
if (status === 'prepared' || status === 'analysing') {
|
||||
analyseBtn.classList.remove('hide', 'disabled');
|
||||
} else if (status === 'start analysis' || status === 'stop analysis') {
|
||||
analyseBtn.classList.remove('hide');
|
||||
analyseBtn.classList.add('disabled');
|
||||
}
|
||||
if (status === 'prepared' || status === 'preparable' || status === 'preparing' || status === 'start analysis' || status === 'analysing' || status === 'stop analysis') {
|
||||
var prepareBtn = document.getElementById('prepare');
|
||||
prepareBtn.classList.add('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var informationUpdater = new InformationUpdater({{ corpus.id }});
|
||||
</script>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<h3 id="title">{{ corpus.title }}</h3>
|
||||
<p id="description">{{ corpus.description }}</p>
|
||||
@ -98,7 +21,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a href="{{ url_for('corpora.corpus_analysis', corpus_id=corpus.id) }}" class="waves-effect waves-light btn hide" id="analyse"><i class="material-icons left">help</i>Analyse</a>
|
||||
<a href="{{ url_for('corpora.analyse_corpus', corpus_id=corpus.id) }}" class="waves-effect waves-light btn hide" id="analyse"><i class="material-icons left">help</i>Analyse</a>
|
||||
{% if corpus.files[0] is defined %}
|
||||
<a href="{{ url_for('corpora.prepare_corpus', corpus_id=corpus.id) }}" class="waves-effect waves-light btn" id="prepare"><i class="material-icons left">whatshot</i>Prepare</a>
|
||||
{% endif %}
|
||||
@ -146,11 +69,12 @@
|
||||
</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>
|
||||
<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="modal-close waves-effect waves-green btn cancel">Cancel</a>
|
||||
@ -169,5 +93,78 @@
|
||||
<a class="modal-close waves-effect waves-green btn red" href="{{ url_for('corpora.delete_corpus_file', corpus_file_id=file.id, corpus_id=corpus.id) }}">Confirm<i class="material-icons right">send</i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
class InformationUpdater {
|
||||
constructor(corpusId, foreignCorpusFlag) {
|
||||
this.corpusId = corpusId;
|
||||
this.foreignCorpusFlag = foreignCorpusFlag;
|
||||
if (this.foreignCorpusFlag) {
|
||||
foreignCorporaSubscribers.push(this);
|
||||
} else {
|
||||
corporaSubscribers.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
_init() {
|
||||
var corpus = this.foreignCorpusFlag ? foreignCorpora[this.corpusId] : corpora[this.corpusId];
|
||||
|
||||
// Status
|
||||
this.setStatus(corpus.status);
|
||||
}
|
||||
|
||||
_update(patch) {
|
||||
var pathArray;
|
||||
|
||||
for (let operation of patch) {
|
||||
/* "/corpusId/valueName" -> ["corpusId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
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) {
|
||||
var statusElement;
|
||||
statusElement = document.getElementById("status");
|
||||
statusElement.classList.remove(...Object.values(CorpusList.STATUS_COLORS));
|
||||
statusElement.classList.add(CorpusList.STATUS_COLORS[status] || CorpusList.STATUS_COLORS['default']);
|
||||
statusElement.innerText = status;
|
||||
var analyseBtn = document.getElementById('analyse');
|
||||
if (status === 'prepared' || status === 'analysing') {
|
||||
analyseBtn.classList.remove('hide', 'disabled');
|
||||
} else if (status === 'start analysis' || status === 'stop analysis') {
|
||||
analyseBtn.classList.remove('hide');
|
||||
analyseBtn.classList.add('disabled');
|
||||
}
|
||||
if (status === 'prepared' || status === 'preparable' || status === 'preparing' || status === 'start analysis' || status === 'analysing' || status === 'stop analysis') {
|
||||
var prepareBtn = document.getElementById('prepare');
|
||||
prepareBtn.classList.add('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{% if corpus.creator == current_user %}
|
||||
var informationUpdater = new InformationUpdater({{ corpus.id }}, false);
|
||||
{% else %}
|
||||
var informationUpdater = new InformationUpdater({{ corpus.id }}, true);
|
||||
socket.emit('subscribe_foreign_user_ressources', {{ corpus.user_id }});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
@ -1,114 +1,6 @@
|
||||
{% extends "limited_width.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<script>
|
||||
{% if job.creator == current_user %}
|
||||
var foreignJobFlag = false;
|
||||
{% else %}
|
||||
var foreignJobFlag = true;
|
||||
socket.emit('subscribe_foreign_user_ressources', {{ job.user_id }});
|
||||
{% endif %}
|
||||
|
||||
class InformationUpdater {
|
||||
constructor(jobId) {
|
||||
this.jobId = jobId;
|
||||
if (foreignJobFlag) {
|
||||
foreignJobsSubscribers.push(this);
|
||||
} else {
|
||||
jobsSubscribers.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
_init() {
|
||||
if (foreignJobFlag) {
|
||||
this.job = foreignJobs[this.jobId];
|
||||
} else {
|
||||
this.job = jobs[this.jobId];
|
||||
}
|
||||
|
||||
// End date
|
||||
this.setEndDate(this.job.end_date);
|
||||
// Status
|
||||
this.setStatus(this.job.status);
|
||||
// End date
|
||||
if (this.job.end_date) {this.setEndDate(this.job.end_date);}
|
||||
// Input results
|
||||
for (let input of this.job.inputs) {
|
||||
for (let result of input.results) {
|
||||
this.setResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_update(patch) {
|
||||
var pathArray;
|
||||
|
||||
for (let operation of patch) {
|
||||
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
if (pathArray[0] != this.jobId) {continue;}
|
||||
switch(operation.op) {
|
||||
case "add":
|
||||
if (pathArray[1] === "inputs" && pathArray[3] === "results") {
|
||||
this.setResult(operation.value);
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
location.reload();
|
||||
break;
|
||||
case "replace":
|
||||
if (pathArray[1] === "end_date") {
|
||||
this.setEndDate(operation.value);
|
||||
} else if (pathArray[1] === "status") {
|
||||
this.setStatus(operation.value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setEndDate(timestamp) {
|
||||
var end_date;
|
||||
if (timestamp === null) {
|
||||
end_date = "N.a.";
|
||||
} else {
|
||||
end_date = new Date(timestamp * 1000).toLocaleString("en-US");
|
||||
}
|
||||
document.getElementById("end-date").value = end_date;
|
||||
M.updateTextFields();
|
||||
}
|
||||
|
||||
setResult(result) {
|
||||
var resultsElement, resultDownloadButtonElement,
|
||||
resultDownloadButtonIconElement;
|
||||
resultsElement = document.getElementById(`input-${result.job_input_id}-results`);
|
||||
resultDownloadButtonElement = document.createElement("a");
|
||||
resultDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
|
||||
resultDownloadButtonElement.href = `/jobs/${this.jobId}/results/${result.id}/download`;
|
||||
resultDownloadButtonElement.innerText = result.filename.split(".").reverse()[0];
|
||||
resultDownloadButtonElement.setAttribute("download", "");
|
||||
resultDownloadButtonIconElement = document.createElement("i");
|
||||
resultDownloadButtonIconElement.classList.add("material-icons", "left");
|
||||
resultDownloadButtonIconElement.innerText = "file_download";
|
||||
resultDownloadButtonElement.prepend(resultDownloadButtonIconElement);
|
||||
resultsElement.append(resultDownloadButtonElement);
|
||||
resultsElement.append(" ");
|
||||
}
|
||||
|
||||
setStatus(status) {
|
||||
var statusElement;
|
||||
statusElement = document.getElementById("status");
|
||||
statusElement.classList.remove(...Object.values(JobList.STATUS_COLORS));
|
||||
statusElement.classList.add(JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default']);
|
||||
statusElement.innerText = status;
|
||||
}
|
||||
}
|
||||
|
||||
var informationUpdater = new InformationUpdater({{ job.id }});
|
||||
</script>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<h3 id="title">{{ job.title }}</h3>
|
||||
<p id="description">{{ job.description }}</p>
|
||||
@ -210,6 +102,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modals -->
|
||||
<div id="delete-job-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
@ -221,4 +114,108 @@
|
||||
<a class="modal-close waves-effect waves-green btn red" href="{{ url_for('jobs.delete_job', job_id=job.id) }}">Confirm<i class="material-icons right">send</i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
class InformationUpdater {
|
||||
constructor(jobId, foreignJobFlag) {
|
||||
this.jobId = jobId;
|
||||
this.foreignJobFlag = foreignJobFlag;
|
||||
if (this.foreignJobFlag) {
|
||||
foreignJobsSubscribers.push(this);
|
||||
} else {
|
||||
jobsSubscribers.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
_init() {
|
||||
var job = this.foreignJobFlag ? foreignJobs[this.jobId] : jobs[this.jobId];
|
||||
|
||||
// End date
|
||||
this.setEndDate(job.end_date);
|
||||
// Status
|
||||
this.setStatus(job.status);
|
||||
// End date
|
||||
if (job.end_date) {this.setEndDate(job.end_date);}
|
||||
// Input results
|
||||
for (let input of job.inputs) {
|
||||
for (let result of input.results) {
|
||||
this.setResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_update(patch) {
|
||||
var pathArray;
|
||||
|
||||
for (let operation of patch) {
|
||||
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
||||
pathArray = operation.path.split("/").slice(1);
|
||||
if (pathArray[0] != this.jobId) {continue;}
|
||||
switch(operation.op) {
|
||||
case "add":
|
||||
if (pathArray[1] === "inputs" && pathArray[3] === "results") {
|
||||
this.setResult(operation.value);
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
location.reload();
|
||||
break;
|
||||
case "replace":
|
||||
if (pathArray[1] === "end_date") {
|
||||
this.setEndDate(operation.value);
|
||||
} else if (pathArray[1] === "status") {
|
||||
this.setStatus(operation.value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setEndDate(timestamp) {
|
||||
var end_date;
|
||||
if (timestamp === null) {
|
||||
end_date = "N.a.";
|
||||
} else {
|
||||
end_date = new Date(timestamp * 1000).toLocaleString("en-US");
|
||||
}
|
||||
document.getElementById("end-date").value = end_date;
|
||||
M.updateTextFields();
|
||||
}
|
||||
|
||||
setResult(result) {
|
||||
var resultsElement, resultDownloadButtonElement,
|
||||
resultDownloadButtonIconElement;
|
||||
resultsElement = document.getElementById(`input-${result.job_input_id}-results`);
|
||||
resultDownloadButtonElement = document.createElement("a");
|
||||
resultDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
|
||||
resultDownloadButtonElement.href = `/jobs/${this.jobId}/results/${result.id}/download`;
|
||||
resultDownloadButtonElement.innerText = result.filename.split(".").reverse()[0];
|
||||
resultDownloadButtonElement.setAttribute("download", "");
|
||||
resultDownloadButtonIconElement = document.createElement("i");
|
||||
resultDownloadButtonIconElement.classList.add("material-icons", "left");
|
||||
resultDownloadButtonIconElement.innerText = "file_download";
|
||||
resultDownloadButtonElement.prepend(resultDownloadButtonIconElement);
|
||||
resultsElement.append(resultDownloadButtonElement);
|
||||
resultsElement.append(" ");
|
||||
}
|
||||
|
||||
setStatus(status) {
|
||||
var statusElement;
|
||||
statusElement = document.getElementById("status");
|
||||
statusElement.classList.remove(...Object.values(JobList.STATUS_COLORS));
|
||||
statusElement.classList.add(JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default']);
|
||||
statusElement.innerText = status;
|
||||
}
|
||||
}
|
||||
|
||||
{% if job.creator == current_user %}
|
||||
var informationUpdater = new InformationUpdater({{ job.id }}, false);
|
||||
{% else %}
|
||||
var informationUpdater = new InformationUpdater({{ job.id }}, true);
|
||||
socket.emit('subscribe_foreign_user_ressources', {{ job.user_id }});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user