mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-06-14 10:00:40 +00:00
Change directory structure (move ./nopaque/* to ./)
This commit is contained in:
31
app/templates/_colors.html.j2
Normal file
31
app/templates/_colors.html.j2
Normal file
@ -0,0 +1,31 @@
|
||||
{% set primary = '#00426f' %}
|
||||
{% set primary_variant = '#1A5C89' %}
|
||||
{% set secondary = '#00426f' %}
|
||||
{% set secondary_variant = '#1A5C89' %}
|
||||
{% set background = '#ffffff' %}
|
||||
{% set surface = '#ffffff' %}
|
||||
{% set error = '#b00020' %}
|
||||
|
||||
{% set service_corpus_analysis = '#aa9cc9' %}
|
||||
{% set service_corpus_analysis_darken = '#6b3f89' %}
|
||||
{% set service_corpus_analysis_lighten = '#ebe8f6' %}
|
||||
{% set service_file_setup = '#d5dc95' %}
|
||||
{% set service_file_setup_darken = '#a1b300' %}
|
||||
{% set service_file_setup_lighten = '#f2f3e1' %}
|
||||
{% set service_nlp = '#98acd2' %}
|
||||
{% set service_nlp_darken = '#0064a3' %}
|
||||
{% set service_nlp_lighten = '#e5e8f5' %}
|
||||
{% set service_ocr = '#a9d8c8' %}
|
||||
{% set service_ocr_darken = '#00a58b' %}
|
||||
{% set service_ocr_lighten = '#e7f4f1' %}
|
||||
|
||||
{% set status_unprepared = '#9e9e9e' %}
|
||||
{% set status_submitted = '#9e9e9e' %}
|
||||
{% set status_queued = '#2196f3' %}
|
||||
{% set status_running = '#ffc107' %}
|
||||
{% set status_complete = '#4caf50' %}
|
||||
{% set status_failed = '#f44336' %}
|
||||
{% set status_prepared = '#4caf50' %}
|
||||
{% set status_start_analysis = '#2196f3' %}
|
||||
{% set status_analysing = '#4caf50' %}
|
||||
{% set status_stop_analysis = '#ff5722' %}
|
40
app/templates/_footer.html.j2
Normal file
40
app/templates/_footer.html.j2
Normal file
@ -0,0 +1,40 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s6 m3">
|
||||
<a href="https://www.dfg.de/">
|
||||
<img class="responsive-img" src="{{ url_for('static', filename='images/logo_-_dfg.gif') }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col s6 m3 offset-m1 center-align">
|
||||
<a href="https://www.uni-bielefeld.de/sfb1288/">
|
||||
<img class="responsive-img" src="{{ url_for('static', filename='images/logo_-_sfb_1288.png') }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col s12 m3 offset-m1">
|
||||
<h5 class="white-text">Legal Notice</h5>
|
||||
<ul>
|
||||
<li><a class="grey-text text-lighten-3" href="https://www.uni-bielefeld.de/(en)/impressum/">Legal Notice</a></li>
|
||||
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.privacy_policy') }}">Privacy statement (GDPR)</a></li>
|
||||
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.terms_of_use') }}">Terms of use</a></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-copyright primary-color">
|
||||
<div class="container">
|
||||
<div class="row" style="margin-bottom: 0;">
|
||||
<div class="col s12 m3">
|
||||
<span>© 2020 Bielefeld University</span>
|
||||
</div>
|
||||
<div class="col s12 m9 right-align">
|
||||
<a class="btn-small blue waves-effect waves-light" href="{{ url_for('main.about_and_faq') }}"><i class="left material-icons">info_outline</i>About and faq</a>
|
||||
{% if config.NOPAQUE_CONTACT %}
|
||||
<a class="btn-small pink waves-effect waves-light" href="mailto:{{ config.NOPAQUE_CONTACT }}?subject={{ config.NOPAQUE_MAIL_SUBJECT_PREFIX }} Contact"><i class="left material-icons">rate_review</i>Contact</a>
|
||||
<a class="btn-small green waves-effect waves-light" href="mailto:{{ config.NOPAQUE_CONTACT }}?subject={{ config.NOPAQUE_MAIL_SUBJECT_PREFIX }} Feedback"><i class="left material-icons">feedback</i>Feedback</a>
|
||||
{% endif %}
|
||||
<a class="btn-small orange waves-effect waves-light" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque"><i class="left material-icons">code</i>GitLab</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
38
app/templates/_navbar.html.j2
Normal file
38
app/templates/_navbar.html.j2
Normal file
@ -0,0 +1,38 @@
|
||||
<div class="navbar-fixed">
|
||||
<nav class="nav-extended">
|
||||
<div class="nav-wrapper primary-color">
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="#" data-target="sidenav" class="sidenav-trigger"><i class="material-icons">menu</i></a>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('main.index') }}" class="brand-logo" style="height: 100%; overflow: hidden;">
|
||||
<img class="hide-on-small-only" src="{{ url_for('static', filename='images/nopaque_-_logo_name_slogan.svg') }}" style="height: 128px; margin-top: -32px; margin-left: -32px;">
|
||||
<img class="hide-on-med-and-up" src="{{ url_for('static', filename='images/nopaque_-_logo.svg') }}" style="height: 128px; margin-top: -32px; margin-left: -32px;">
|
||||
</a>
|
||||
<ul class="right">
|
||||
<li><a class="dropdown-trigger no-autoinit" data-target="nav-more-dropdown" href="#!" id="nav-more-dropdown-trigger"><i class="material-icons">more_vert</i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="nav-content primary-variant-color">
|
||||
<ul class="tabs tabs-transparent">
|
||||
<li class="tab"><a href="{{ url_for('main.index') }}" target="_self"><i class="material-icons">home</i></a></li>
|
||||
{% if breadcrumbs is defined %}
|
||||
{{ breadcrumbs }}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% if current_user.is_authenticated %}
|
||||
<a class="btn-floating btn-large halfway-fab modal-trigger pink tooltipped waves-effect waves-light" data-tooltip="Roadmap" href="#roadmap-modal"><i class="material-icons">explore</i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<ul class="dropdown-content" id="nav-more-dropdown">
|
||||
{% if current_user.is_authenticated %}
|
||||
<li><a href="{{ url_for('settings.index') }}"><i class="material-icons left">settings</i>Settings</a></li>
|
||||
<li class="divider" tabindex="-1"></li>
|
||||
<li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
|
||||
{% else %}
|
||||
<li{% if request.path == url_for('auth.register') %} class="active"{% endif %}><a href="{{ url_for('auth.register') }}"><i class="material-icons left">assignment</i>Register</a></li>
|
||||
<li{% if request.path == url_for('auth.login') %} class="active"{% endif %}><a href="{{ url_for('auth.login') }}"><i class="material-icons left">login</i>Log in</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
34
app/templates/_roadmap.html.j2
Normal file
34
app/templates/_roadmap.html.j2
Normal file
@ -0,0 +1,34 @@
|
||||
<div id="roadmap-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h2>Roadmap</h2>
|
||||
<p>The roadmap guides you through nopaque's workflow! If you have the necessary input fie formats, you can directly jump into the corresponding process. If not, you can use the roadmap to jump right to the preceding process.</p>
|
||||
<ul class="tabs tabs-fixed-width">
|
||||
<li class="tab"><a{%if request.path == url_for('services.service', service='file-setup') %} class="active"{% endif %} href="{{ url_for('services.service', service='file-setup') }}" target="_self">File setup</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a{%if request.path == url_for('services.service', service='ocr') %} class="active"{% endif %} href="{{ url_for('services.service', service='ocr') }}" target="_self">OCR</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a{%if request.path == url_for('services.service', service='nlp') %} class="active"{% endif %} href="{{ url_for('services.service', service='nlp') }}" target="_self">NLP</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a{%if request.path == url_for('corpora.add_corpus') %} class="active"{% endif %} href="{{ url_for('corpora.add_corpus') }}" target="_self">Add corpus</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if corpus %}
|
||||
<li class="tab"><a{%if request.path == url_for('corpora.add_corpus_file', corpus_id=corpus.id) %} class="active"{% endif %} href="{{ url_for('corpora.add_corpus_file', corpus_id=corpus.id) }}" target="_self">Add corpus file(s)</a></li>
|
||||
{% else %}
|
||||
<li class="tab disabled tooltipped" data-tooltip="Select a corpus first" target="_self"><a>Add corpus file(s)</a></li>
|
||||
{% endif %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if corpus %}
|
||||
{% if corpus.files.all() %}
|
||||
<li class="tab"><a{%if request.path == url_for('corpora.analyse_corpus', corpus_id=corpus.id) %} class="active"{% endif %} href="{{ url_for('corpora.analyse_corpus', corpus_id=corpus.id) }}" target="_self">Corpus analysis</a></li>
|
||||
{% else %}
|
||||
<li class="tab disabled tooltipped" data-tooltip="Add at least one corpus file first"><a>Corpus analysis</a></li>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<li class="tab disabled tooltipped" data-tooltip="Select a corpus first"><a>Corpus analysis</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn-flat">Close</a>
|
||||
</div>
|
||||
</div>
|
37
app/templates/_scripts.html.j2
Normal file
37
app/templates/_scripts.html.j2
Normal file
@ -0,0 +1,37 @@
|
||||
{% if current_user.setting_dark_mode %}
|
||||
<script src="{{ url_for('static', filename='js/darkreader.js') }}"></script>
|
||||
<script>
|
||||
DarkReader.enable({brightness: 150, contrast: 100, sepia: 0});
|
||||
</script>
|
||||
{% endif %}
|
||||
<script src="{{ url_for('static', filename='js/jsonpatch.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/list.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/socket.io.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/nopaque/main.js') }}"></script>
|
||||
{% assets filters='rjsmin', output="js/nopaque/RessourceDisplays.min.bundle.js",
|
||||
"js/nopaque/RessourceDisplays/RessourceDisplay.js",
|
||||
"js/nopaque/RessourceDisplays/CorpusDisplay.js",
|
||||
"js/nopaque/RessourceDisplays/JobDisplay.js" %}
|
||||
<script src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
{% assets filters='rjsmin', output="js/nopaque/RessourceLists.min.bundle.js",
|
||||
"js/nopaque/RessourceLists/RessourceList.js",
|
||||
"js/nopaque/RessourceLists/CorpusList.js",
|
||||
"js/nopaque/RessourceLists/CorpusFileList.js",
|
||||
"js/nopaque/RessourceLists/JobList.js",
|
||||
"js/nopaque/RessourceLists/JobInputList.js",
|
||||
"js/nopaque/RessourceLists/JobResultList.js",
|
||||
"js/nopaque/RessourceLists/QueryResultList.js",
|
||||
"js/nopaque/RessourceLists/UserList.js" %}
|
||||
<script src="{{ ASSET_URL }}"></script>
|
||||
{% endassets %}
|
||||
<script>
|
||||
// Disable all option elements with no value
|
||||
for (let optionElement of document.querySelectorAll('option[value=""]')) {optionElement.disabled = true;}
|
||||
M.AutoInit();
|
||||
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="email"], input[data-length][type="password"], input[data-length][type="text"], textarea[data-length]'));
|
||||
M.Dropdown.init(document.querySelectorAll('#nav-more-dropdown-trigger'), {alignment: 'right', constrainWidth: false, coverTrigger: false});
|
||||
nopaque.appClient = new AppClient({% if current_user.is_authenticated %}{{ current_user.id }}{% endif %});
|
||||
nopaque.Forms.init();
|
||||
for (let flashedMessage of {{ get_flashed_messages(with_categories=True)|tojson }}) {nopaque.appClient.flash(flashedMessage[1], flashedMessage[0]);}
|
||||
</script>
|
30
app/templates/_sidenav.html.j2
Normal file
30
app/templates/_sidenav.html.j2
Normal file
@ -0,0 +1,30 @@
|
||||
<ul class="sidenav sidenav-fixed" id="sidenav">
|
||||
<li>
|
||||
<div class="user-view">
|
||||
<div class="background primary-color"></div>
|
||||
<span class="white-text name">{{ current_user.username }}</span>
|
||||
<span class="white-text email">{{ current_user.email }}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="{{ url_for('main.index') }}">nopaque</a></li>
|
||||
<li><a href="{{ url_for('main.news') }}"><i class="material-icons left">email</i>News</a></li>
|
||||
<li><a href="#"><i class="material-icons">linear_scale</i>Workflow</a></li>
|
||||
<li><a href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a></li>
|
||||
<li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="nopaque-icons">I</i>My Corpora</a></li>
|
||||
<li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">Processes & Services</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="file-setup" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='file_setup') }}"><i class="nopaque-icons service-icon" data-service="file-setup"></i>File setup</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="ocr" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="nopaque-icons service-icon" data-service="ocr"></i>OCR</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="nlp" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="nopaque-icons service-icon" data-service="nlp"></i>NLP</a></li>
|
||||
<li class="service-color service-color-border border-darken" data-service="corpus-analysis" style="border-left: 10px solid; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="nopaque-icons service-icon" data-service="corpus-analysis"></i>Corpus analysis</a></li>
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">Account</a></li>
|
||||
<li><a href="{{ url_for('settings.index') }}"><i class="material-icons">settings</i>Settings</a></li>
|
||||
<li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
|
||||
{% if current_user.is_administrator() %}
|
||||
<li><div class="divider"></div></li>
|
||||
<li><a class="subheader">Administration</a></li>
|
||||
<li><a href="{{ url_for('admin.index') }}"><i class="material-icons">build</i>Administration</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
83
app/templates/_styles.html.j2
Normal file
83
app/templates/_styles.html.j2
Normal file
@ -0,0 +1,83 @@
|
||||
{% import "_colors.html.j2" as colors %}
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<link href="{{ url_for('static', filename='css/sidenav_fixed.css') }}" media="screen,projection" rel="stylesheet">
|
||||
{% endif %}
|
||||
<link href="{{ url_for('static', filename='css/nopaque_icons.css') }}" media="screen,projection" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/sticky_footer.css') }}" media="screen,projection" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/materialize_fixes.css') }}" media="screen,projection" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/nopaque.css') }}" media="screen,projection" rel="stylesheet">
|
||||
<style>
|
||||
.primary-color {background-color: {{ colors['primary'] }} !important;}
|
||||
.primary-color-border {border-color: {{ colors['primary'] }} !important;}
|
||||
.primary-color-text {color: {{ colors['primary'] }} !important;}
|
||||
.primary-variant-color {background-color: {{ colors['primary_variant'] }} !important;}
|
||||
.primary-variant-color-border {border-color: {{ colors['primary_variant'] }} !important;}
|
||||
.primary-variant-color-text {color: {{ colors['primary_variant'] }} !important;}
|
||||
|
||||
.secondary-color {background-color: {{ colors['secondary'] }} !important;}
|
||||
.secondary-color-border {border-color: {{ colors['secondary'] }} !important;}
|
||||
.secondary-color-text {color: {{ colors['secondary'] }} !important;}
|
||||
.secondary-variant-color {background-color: {{ colors['secondary_variant'] }} !important;}
|
||||
.secondary-variant-color-border {border-color: {{ colors['secondary_variant'] }} !important;}
|
||||
.secondary-variant-color-text {color: {{ colors['secondary_variant'] }} !important;}
|
||||
|
||||
.background-color {background-color: {{ colors['background'] }} !important;}
|
||||
.background-color-border {border-color: {{ colors['background'] }} !important;}
|
||||
.background-color-text {color: {{ colors['background'] }} !important;}
|
||||
|
||||
.surface-color {background-color: {{ colors['surface'] }} !important;}
|
||||
.surface-color-border {border-color: {{ colors['surface'] }} !important;}
|
||||
.surface-color-text {color: {{ colors['surface'] }} !important;}
|
||||
|
||||
.error-color {background-color: {{ colors['error'] }} !important;}
|
||||
.error-color-border {border-color: {{ colors['error'] }} !important;}
|
||||
.error-color-text {color: {{ colors['error'] }} !important;}
|
||||
|
||||
main .btn, main .btn-small, main .btn-large, main .btn-floating {background-color: {{ colors['secondary'] }};}
|
||||
main .btn:hover, main .btn-large:hover, main .btn-small:hover, main .btn-floating:hover {background-color: {{ colors['secondary_variant'] }};}
|
||||
main .pagination li.active {background-color: {{ colors['secondary'] }};}
|
||||
main .table-of-contents a.active {border-color: {{ colors['secondary'] }};}
|
||||
main .tabs .tab a {color: inherit;}
|
||||
main .tabs .tab.disabled a, main .tabs .tab.disabled a:hover {color: {{ colors['secondary'] }}28;}
|
||||
main .tabs .tab a:hover {color: {{ colors['secondary'] }};}
|
||||
main .tabs .tab a.active, main .tabs .tab a:focus.active {color: {{ colors['secondary'] }}; background-color: {{ colors['secondary'] }}28;}
|
||||
main .tabs .indicator {background-color: {{ colors['secondary'] }};}
|
||||
|
||||
{% for service in ['file-setup', 'ocr', 'nlp', 'corpus-analysis'] %}
|
||||
{% set service_color = colors['service_' + service.replace('-', '_')] %}
|
||||
{% set service_color_darken = colors['service_' + service.replace('-', '_') + '_darken'] %}
|
||||
{% set service_color_lighten = colors['service_' + service.replace('-', '_') + '_lighten'] %}
|
||||
.service-scheme[data-service="{{ service }}"] {background-color: {{ service_color_lighten }};}
|
||||
.service-scheme[data-service="{{ service }}"] .btn, .service-scheme[data-service="{{ service }}"] .btn-small, .service-scheme[data-service="{{ service }}"] .btn-large, .service-scheme[data-service="{{ service }}"] .btn-floating {background-color: {{ service_color_darken }};}
|
||||
.service-scheme[data-service="{{ service }}"] .btn:hover, .service-scheme[data-service="{{ service }}"] .btn-large:hover, .service-scheme[data-service="{{ service }}"] .btn-small:hover, .service-scheme[data-service="{{ service }}"] .btn-floating:hover {background-color: {{ service_color }};}
|
||||
.service-scheme[data-service="{{ service }}"] .pagination li.active {background-color: {{ service_color_darken }};}
|
||||
.service-scheme[data-service="{{ service }}"] .table-of-contents a.active {border-color: {{ service_color_darken }};}
|
||||
.service-scheme[data-service="{{ service }}"] .tabs .tab a {color: inherit;}
|
||||
.service-scheme[data-service="{{ service }}"] .tabs .tab.disabled a, .service-scheme[data-service="{{ service }}"] .tabs .tab.disabled a:hover {color: {{ service_color_darken }}28;}
|
||||
.service-scheme[data-service="{{ service }}"] .tabs .tab a:hover {color: {{ service_color_darken }};}
|
||||
.service-scheme[data-service="{{ service }}"] .tabs .tab a.active, .service-scheme[data-service="{{ service }}"] .tabs .tab a:focus.active {color: {{ service_color_darken }}; background-color: {{ service_color_darken }}28;}
|
||||
.service-scheme[data-service="{{ service }}"] .tabs .indicator {background-color: {{ service_color_darken }};}
|
||||
|
||||
.service-color[data-service="{{ service }}"] {background-color: {{ service_color }} !important;}
|
||||
.service-color-text[data-service="{{ service }}"] {color: {{ service_color }} !important;}
|
||||
.service-color-border[data-service="{{ service }}"] {border-color: {{ service_color }} !important;}
|
||||
.service-color[data-service="{{ service }}"].darken {background-color: {{ service_color_darken }} !important;}
|
||||
.service-color-text[data-service="{{ service }}"].text-darken {color: {{ service_color_darken }} !important;}
|
||||
.service-color-border[data-service="{{ service }}"].border-darken {border-color: {{ service_color_darken }} !important;}
|
||||
.service-color[data-service="{{ service }}"].lighten {background-color: {{ service_color_lighten }} !important;}
|
||||
.service-color-text[data-service="{{ service }}"].text-lighten {color: {{ service_color_lighten }} !important;}
|
||||
.service-color-border[data-service="{{ service }}"].border-lighten {border-color: {{ service_color_lighten }} !important;}
|
||||
{% endfor %}
|
||||
|
||||
.status-color[data-status="unprepared"] {background-color: {{ colors.status_unprepared }} !important;}
|
||||
.status-color[data-status="submitted"] {background-color: {{ colors.status_submitted }} !important;}
|
||||
.status-color[data-status="queued"] {background-color: {{ colors.status_queued }} !important;}
|
||||
.status-color[data-status="running"] {background-color: {{ colors.status_running }} !important;}
|
||||
.status-color[data-status="complete"] {background-color: {{ colors.status_complete }} !important;}
|
||||
.status-color[data-status="failed"] {background-color: {{ colors.status_failed }} !important;}
|
||||
.status-color[data-status="prepared"] {background-color: {{ colors.status_prepared }} !important;}
|
||||
.status-color[data-status="start analysis"] {background-color: {{ colors.status_start_analysis }} !important;}
|
||||
.status-color[data-status="analysing"] {background-color: {{ colors.status_analysing }} !important;}
|
||||
.status-color[data-status="stop analysis"] {background-color: {{ colors.status_stop_analysis }} !important;}
|
||||
</style>
|
18
app/templates/admin/_breadcrumbs.html.j2
Normal file
18
app/templates/admin/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,18 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('.index') }}" target="_self">Administration</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('.users') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.users') }}" target="_self">Users</a></li>
|
||||
{% elif request.path == url_for('.user', user_id=user.id) %}
|
||||
<li class="tab"><a href="{{ url_for('.users') }}" target="_self">Users</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a class="active" href="{{ url_for('.user', user_id=user.id) }}" target="_self">{{ user.username }}</a></li>
|
||||
{% elif request.path == url_for('.edit_user', user_id=user.id) %}
|
||||
<li class="tab"><a href="{{ url_for('.users') }}" target="_self">Users</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('.user', user_id=user.id) }}" target="_self">{{ user.username }}</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a class="active" href="{{ url_for('.edit_user', user_id=user.id) }}" target="_self">Edit</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
71
app/templates/admin/edit_user.html.j2
Normal file
71
app/templates/admin/edit_user.html.j2
Normal file
@ -0,0 +1,71 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "admin/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">Edit user</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<h2>{{ user.username }}</h2>
|
||||
<p>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('.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">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.username, data_length='64', material_icon='account_circle') }}
|
||||
{{ wtf.render_field(form.email, class_='validate', material_icon='email', type='email') }}
|
||||
{{ wtf.render_field(form.role, material_icon='swap_vert') }}
|
||||
<div class="row">
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s1">
|
||||
<p><i class="material-icons">brightness_3</i></p>
|
||||
</div>
|
||||
<div class="col s8">
|
||||
<p>{{ form.dark_mode.label.text }}</p>
|
||||
<p class="light">Enable dark mode to ease your eyes.</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
{{ form.dark_mode() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s1">
|
||||
<p><i class="material-icons">check</i></p>
|
||||
</div>
|
||||
<div class="col s8">
|
||||
<p>{{ form.confirmed.label.text }}</p>
|
||||
<p class="light">Change confirmation status manually.</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
{{ form.confirmed() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
118
app/templates/admin/user.html.j2
Normal file
118
app/templates/admin/user.html.j2
Normal file
@ -0,0 +1,118 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "admin/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<h2>{{ user.username }}</h2>
|
||||
<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('.users') }}"><i class="material-icons left">arrow_back</i>Back to Users</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>Member since: {{ user.member_since.strftime('%m/%d/%Y, %H:%M:%S %p') }}</li>
|
||||
<li>Confirmed status: {{ user.confirmed }}</li>
|
||||
<li>Last seen: {{ user.last_seen.strftime('%m/%d/%Y, %H:%M:%S %p') }}</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('.edit_user', user_id=user.id) }}" class="waves-effect waves-light btn"><i class="material-icons left">edit</i>Edit</a>
|
||||
<a data-target="delete-user-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 l6" id="corpora" data-user-id="{{ user.id }}">
|
||||
<h3>Corpora</h3>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-corpus" class="search" type="search"></input>
|
||||
<label for="search-corpus">Search corpus</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th><span class="sort" data-sort="status">Status</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 l6" id="jobs" data-user-id="{{ user.id }}">
|
||||
<h3>Jobs</h3>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-job" class="search" type="search"></input>
|
||||
<label for="search-job">Search job</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span class="sort" data-sort="service">Service</span></th>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th><span class="sort" data-sort="status">Status</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modals -->
|
||||
<div id="delete-user-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h3>Delete user</h3>
|
||||
<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-light btn">Cancel</a>
|
||||
<a href="{{ url_for('.delete_user', user_id=user.id) }}" class="modal-close waves-effect waves-light btn red"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
nopaque.appClient.loadUser({{ user.id }});
|
||||
let corpusList = new CorpusList(document.querySelector('#corpora'));
|
||||
let jobList = new JobList(document.querySelector('#jobs'));
|
||||
</script>
|
||||
{% endblock scripts %}
|
46
app/templates/admin/users.html.j2
Normal file
46
app/templates/admin/users.html.j2
Normal file
@ -0,0 +1,46 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "admin/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="users">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<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 class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort" data-sort="id">Id</th>
|
||||
<th class="sort" data-sort="username">Username</th>
|
||||
<th class="sort" data-sort="email">Email</th>
|
||||
<th class="sort" data-sort="last_seen">Last seen</th>
|
||||
<th class="sort" data-sort="role">Role</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
let userList = new UserList(document.querySelector('#users'), {page: 10});
|
||||
userList.init({{ users|tojson }});
|
||||
</script>
|
||||
{% endblock scripts %}
|
14
app/templates/auth/_breadcrumbs.html.j2
Normal file
14
app/templates/auth/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,14 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('.login') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.login') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.register') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.register') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.reset_password', token=token) %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.reset_password', token=token) }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.reset_password_request') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.reset_password_request') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.unconfirmed') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.unconfirmed') }}" target="_self">{{ title }}</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
7
app/templates/auth/email/confirm.html.j2
Normal file
7
app/templates/auth/email/confirm.html.j2
Normal file
@ -0,0 +1,7 @@
|
||||
<p>Dear {{ user.username }},</p>
|
||||
<p>to confirm your account please <a href="{{ url_for('auth.confirm', token=token, _external=True) }}">click here</a>.</p>
|
||||
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
|
||||
<p>{{ url_for('auth.confirm', token=token, _external=True) }}</p>
|
||||
<p>Sincerely,</p>
|
||||
<p>The nopaque Team</p>
|
||||
<p><small>Note: replies to this email address are not monitored.</small></p>
|
9
app/templates/auth/email/confirm.txt.j2
Normal file
9
app/templates/auth/email/confirm.txt.j2
Normal file
@ -0,0 +1,9 @@
|
||||
Dear {{ user.username }},
|
||||
|
||||
to confirm your account please click on the following link:
|
||||
{{ url_for('auth.confirm', token=token, _external=True) }}
|
||||
|
||||
Sincerely,
|
||||
The nopaque Team
|
||||
|
||||
Note: replies to this email address are not monitored.
|
8
app/templates/auth/email/reset_password.html.j2
Normal file
8
app/templates/auth/email/reset_password.html.j2
Normal file
@ -0,0 +1,8 @@
|
||||
<p>Dear {{ user.username }},</p>
|
||||
<p>to reset your password <a href="{{ url_for('auth.reset_password', token=token, _external=True) }}">click here</a>.</p>
|
||||
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
|
||||
<p>{{ url_for('auth.reset_password', token=token, _external=True) }}</p>
|
||||
<p>If you have not requested a password reset simply ignore this message.</p>
|
||||
<p>Sincerely,</p>
|
||||
<p>The nopaque Team</p>
|
||||
<p><small>Note: replies to this email address are not monitored.</small></p>
|
13
app/templates/auth/email/reset_password.txt.j2
Normal file
13
app/templates/auth/email/reset_password.txt.j2
Normal file
@ -0,0 +1,13 @@
|
||||
Dear {{ user.username }},
|
||||
|
||||
to reset your password click on the following link:
|
||||
|
||||
{{ url_for('auth.reset_password', token=token, _external=True) }}
|
||||
|
||||
If you have not requested a password reset simply ignore this message.
|
||||
|
||||
Sincerely,
|
||||
|
||||
The nopaque Team
|
||||
|
||||
Note: replies to this email address are not monitored.
|
55
app/templates/auth/login.html.j2
Normal file
55
app/templates/auth/login.html.j2
Normal file
@ -0,0 +1,55 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "auth/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
main {
|
||||
background-image: url("{{ url_for('static', filename='images/parallax_lq/04_german_text_book_paper.jpg') }}");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
||||
{% endblock styles %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
<div class="card medium">
|
||||
<div class="card-content">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<p>Want to boost your research and get going? nopaque is free and no download is needed. Register now!</p>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="btn" href="{{ url_for('.register') }}"><i class="material-icons left">person_add</i>Register</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card medium">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.user, material_icon='person') }}
|
||||
{{ wtf.render_field(form.password, material_icon='vpn_key') }}
|
||||
<div class="row" style="margin-bottom: 0;">
|
||||
<div class="col s6 left-align">
|
||||
<a href="{{ url_for('.reset_password_request') }}">Forgot your password?</a>
|
||||
</div>
|
||||
<div class="col s6 right-align">
|
||||
{{ wtf.render_field(form.remember_me) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
48
app/templates/auth/register.html.j2
Normal file
48
app/templates/auth/register.html.j2
Normal file
@ -0,0 +1,48 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "auth/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
main {
|
||||
background-image: url("{{ url_for('static', filename='images/parallax_lq/02_concept_document_focus_letter.jpg') }}");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
||||
{% endblock styles %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
<div class="card medium">
|
||||
<div class="card-content">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<p>Simply enter a username and password to receive your registration email. After that you can start right away.</p>
|
||||
<p>It goes without saying that the <a href="{{ url_for('main.privacy_policy') }}">General Data Protection Regulation</a> applies, only necessary data is stored.</p>
|
||||
<p>Please also read our <a href="{{ url_for('main.terms_of_use') }}">terms of use</a> before signing up for nopaque!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card medium">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.username, data_length='64', material_icon='person') }}
|
||||
{{ wtf.render_field(form.password, data_length='128', material_icon='vpn_key') }}
|
||||
{{ wtf.render_field(form.password_confirmation, data_length='128', material_icon='vpn_key') }}
|
||||
{{ wtf.render_field(form.email, class_='validate', material_icon='email', type='email') }}
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
32
app/templates/auth/reset_password.html.j2
Normal file
32
app/templates/auth/reset_password.html.j2
Normal file
@ -0,0 +1,32 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "auth/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<p>Enter a new password and confirm it! After that, the entered password is your new one!</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.password, data_length='128') }}
|
||||
{{ wtf.render_field(form.password_confirmation, data_length='128') }}
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
31
app/templates/auth/reset_password_request.html.j2
Normal file
31
app/templates/auth/reset_password_request.html.j2
Normal file
@ -0,0 +1,31 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "auth/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<p>After entering your email address you will receive instructions on how to reset your password.</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.email, class_='validate', material_icon='email', type='email') }}
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
26
app/templates/auth/unconfirmed.html.j2
Normal file
26
app/templates/auth/unconfirmed.html.j2
Normal file
@ -0,0 +1,26 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "auth/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Hello, {{ current_user.username }}!</span>
|
||||
<p><b>You have not confirmed your account yet.</b></p>
|
||||
<p>Before you can access this site you need to confirm your account. Check your inbox, you should have received an email with a confirmation link.</p>
|
||||
<p>Need another confirmation email? Click the button below!</p>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="btn" href="{{ url_for('.resend_confirmation') }}">Resend confirmation mail</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
51
app/templates/base.html.j2
Normal file
51
app/templates/base.html.j2
Normal file
@ -0,0 +1,51 @@
|
||||
{% extends "materialize/base.html.j2" %}
|
||||
{% import "_colors.html.j2" as colors %}
|
||||
|
||||
{% block html_attribs %} lang="en"{% endblock html_attribs %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<link href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}" rel="icon">
|
||||
{% endblock head %}
|
||||
|
||||
{% block metas %}
|
||||
<meta charset="UTF-8">
|
||||
{{ super() }}
|
||||
{% endblock metas %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock title %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
{% include "_styles.html.j2" %}
|
||||
{% endblock styles %}
|
||||
|
||||
{% block navbar %}
|
||||
{% include "_navbar.html.j2" %}
|
||||
{% endblock navbar %}
|
||||
|
||||
{% block sidenav %}
|
||||
{% if current_user.is_authenticated %}
|
||||
{% include "_sidenav.html.j2" %}
|
||||
{% endif %}
|
||||
{% endblock sidenav %}
|
||||
|
||||
{% block main_attribs %} class="background-color"{% endblock main_attribs %}
|
||||
{% block main %}
|
||||
{% block page_content %}{% endblock page_content %}
|
||||
<div id="modals">
|
||||
{% if current_user.is_authenticated %}
|
||||
{% include "_roadmap.html.j2" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock main %}
|
||||
|
||||
{% block footer_attribs %} class="page-footer primary-variant-color"{% endblock footer_attribs %}
|
||||
{% block footer %}
|
||||
{% include "_footer.html.j2" %}
|
||||
{% endblock footer %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
{% include "_scripts.html.j2" %}
|
||||
{% endblock scripts %}
|
28
app/templates/corpora/_breadcrumbs.html.j2
Normal file
28
app/templates/corpora/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,28 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" target="_self">My corpora</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('.add_corpus') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.add_corpus') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.import_corpus') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.import_corpus') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.corpus', corpus_id=corpus.id) %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.corpus', corpus_id=corpus.id) }}" target="_self">{{ corpus.title }}</a></li>
|
||||
{% elif request.path == url_for('.analyse_corpus', corpus_id=corpus.id) %}
|
||||
<li class="tab"><a href="{{ url_for('.corpus', corpus_id=corpus.id) }}" target="_self">{{ corpus.title }}</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a class="active" href="{{ url_for('.analyse_corpus', corpus_id=corpus.id) }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.add_corpus_file', corpus_id=corpus.id) %}
|
||||
<li class="tab"><a href="{{ url_for('.corpus', corpus_id=corpus.id) }}" target="_self">{{ corpus.title }}</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('.corpus', corpus_id=corpus.id, _anchor='files') }}" target="_self">Corpus files</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a class="active" href="{{ url_for('.add_corpus_file', corpus_id=corpus.id) }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.corpus_file', corpus_file_id=corpus_file.id, corpus_id=corpus.id) %}
|
||||
<li class="tab"><a href="{{ url_for('.corpus', corpus_id=corpus.id) }}" target="_self">{{ corpus.title }}</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('.corpus', corpus_id=corpus.id, _anchor='files') }}" target="_self">Corpus files</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a class="active" href="{{ url_for('.corpus_file', corpus_file_id=corpus_file.id, corpus_id=corpus.id) }}" target="_self">{{ corpus_file.author }}: {{ corpus_file.title }} ({{ corpus_file.publishing_year }})</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
41
app/templates/corpora/add_corpus.html.j2
Normal file
41
app/templates/corpora/add_corpus.html.j2
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<p>Fill out the following form to 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">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.title, data_length='32', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 m8">
|
||||
{{ wtf.render_field(form.description, data_length='255', material_icon='description') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
86
app/templates/corpora/add_corpus_file.html.j2
Normal file
86
app/templates/corpora/add_corpus_file.html.j2
Normal file
@ -0,0 +1,86 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<p>Fill out the following form to add a corpus file in verticalized text format (.vrt).</p>
|
||||
<p><b>Do not use the .stand-off.vrt file!</b></p>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<form class="nopaque-submit-form" data-progress-modal="progress-modal">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.author, data_length='255', material_icon='person') }}
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.title, data_length='255', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.publishing_year, material_icon='access_time') }}
|
||||
</div>
|
||||
<div class="col s12">
|
||||
{{ wtf.render_field(form.file, accept='.vrt', placeholder='Choose your .vrt file') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(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 form
|
||||
if field.short_name not in ['author', 'csrf_token', 'file', 'publishing_year', 'submit', 'title'] %}
|
||||
{{ wtf.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>
|
||||
</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 %}
|
337
app/templates/corpora/analyse_corpus.html.j2
Normal file
337
app/templates/corpora/analyse_corpus.html.j2
Normal file
@ -0,0 +1,337 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<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 class="col s12" id="query-form">
|
||||
<div class="row">
|
||||
<div class="input-field col s12 m10">
|
||||
<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/" target="_blank">
|
||||
<i class="material-icons" style="font-size: inherit;">help
|
||||
</i>
|
||||
CQP query language tutorial
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col s12 m2 right-align" style="margin-top: 1.75em;">
|
||||
<a class="waves-effect waves-light btn modal-trigger" href="#query-builder-modal"><i class="material-icons left">build</i> Query builder</a>
|
||||
{{ wtf.render_field(query_form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</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 id="interactions-menu" class="row hide"
|
||||
style="margin-bottom: 0px;">
|
||||
{# Importing menus for query settings, export etc. #}
|
||||
{% include 'corpora/interactions/infos.html.j2' %}
|
||||
{% include 'corpora/interactions/export.html.j2' %}
|
||||
{% include 'corpora/interactions/create.html.j2' %}
|
||||
{% include 'corpora/interactions/display.html.j2' %}
|
||||
</div>
|
||||
{% include 'tables/query_results.html.j2' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scroll to top element -->
|
||||
{% include 'corpora/interactions/scroll_to_top.html.j2' %}
|
||||
|
||||
<!-- Modals -->
|
||||
{% include 'modals/query_builder.html.j2' %}
|
||||
{% include 'modals/show_metadata.html.j2' %}
|
||||
{% include 'modals/analysis_init.html.j2' %}
|
||||
{% include 'modals/export_query_results.html.j2' %}
|
||||
{% include 'modals/context_modal.html.j2' %}
|
||||
{% include 'modals/show_corpus_files.html.j2' %}
|
||||
{% endblock page_content %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<!-- import modules -->
|
||||
<script type="module">
|
||||
/**
|
||||
* First Phase:
|
||||
* Document content is loaded and scripts are being imported and executed.
|
||||
*/
|
||||
|
||||
// Import Client classes. Client handles the server client communication.
|
||||
import {
|
||||
Client,
|
||||
ClientEventListener,
|
||||
ListenerCallback,
|
||||
} from '../../static/js/modules/corpus_analysis/client/Client.js';
|
||||
/**
|
||||
* Import Client listener functions which will listen for defined socket or
|
||||
* javascript events.
|
||||
*/
|
||||
import {
|
||||
recieveConnected,
|
||||
recieveMetaData,
|
||||
recieveQueryStatus,
|
||||
recieveQueryData,
|
||||
recieveViewNotification,
|
||||
recieveResultsData,
|
||||
} from '../../static/js/modules/corpus_analysis/client/listeners.js';
|
||||
// Import client listener callbacks so they can be registered to the listeners.
|
||||
import {
|
||||
prepareQueryData,
|
||||
saveQueryData,
|
||||
saveMetaData,
|
||||
getResultsData,
|
||||
saveResultsData,
|
||||
} from '../../static/js/modules/corpus_analysis/client/callbacks.js';
|
||||
// Import Results class which will be used to save results data of a query etc.
|
||||
import {
|
||||
Results,
|
||||
} from '../../static/js/modules/corpus_analysis/model/Results.js';
|
||||
/**
|
||||
* Import the ResultsList which can be understood as a View class that handles
|
||||
* how the data from Results is represented to the user. The ViewEventListener
|
||||
* is used to register listener functions which listen for events emitred by
|
||||
* the Client.
|
||||
*/
|
||||
import {
|
||||
ResultsList,
|
||||
ViewEventListener,
|
||||
} from '../../static/js/modules/corpus_analysis/view/ResultsView.js';
|
||||
// Import listener which will be registered to the ViewEventListener class.
|
||||
import {
|
||||
// listener listening for client dispatched 'notify-vie' custom event.
|
||||
recieveClientNotification,
|
||||
// vanilla javascript Event listeners which are listening for button clicks.
|
||||
pageNavigation,
|
||||
expertModeSwitch,
|
||||
actionButtons,
|
||||
displayOptions,
|
||||
showMetaData,
|
||||
showCorpusFiles,
|
||||
exportFullContextSwitch,
|
||||
createFullResults,
|
||||
createSubResults,
|
||||
exportFullResults,
|
||||
exportSubResults,
|
||||
exportSingleMatch,
|
||||
} from '../../static/js/modules/corpus_analysis/view/listeners.js';
|
||||
// Import script that implements the scroll to top button.
|
||||
import {
|
||||
scrollToTop,
|
||||
} from '../../static/js/modules/corpus_analysis/view/scrollToTop.js';
|
||||
// vanilla javascript Event listeners which are listening for button clicks etc
|
||||
|
||||
|
||||
/**
|
||||
* Second Phase:
|
||||
* Asynchronus and event driven code.
|
||||
*/
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Initialize the client for server client communication in dynamic mode
|
||||
let corpusId = {{ corpus.id }}
|
||||
const client = new Client({'corpusId': corpusId,
|
||||
'socket': nopaque.appClient.socket,
|
||||
'logging': true,
|
||||
'dynamicMode': true});
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* Register listeners listening to socket.io events and their callbacks
|
||||
* Afterwards load them. Also registers listeners listening for custom
|
||||
* javascript events emitted by the View.
|
||||
*/
|
||||
const listenForConnected = new ClientEventListener('corpus_analysis_init',
|
||||
recieveConnected);
|
||||
const listenForMetaData = new ClientEventListener('corpus_analysis_meta_data',
|
||||
recieveMetaData);
|
||||
const metaDataCallback = new ListenerCallback('corpus_analysis_meta_data',
|
||||
saveMetaData,
|
||||
[client, results]);
|
||||
listenForMetaData.setCallbacks([metaDataCallback]);
|
||||
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,
|
||||
[client, results]);
|
||||
listenForQueryData.setCallbacks([queryDataCallback]);
|
||||
const listenForResults = new ClientEventListener('corpus_analysis_get_match_with_full_context',
|
||||
recieveResultsData);
|
||||
const resultsDataCallback = new ListenerCallback('corpus_analysis_get_match_with_full_context',
|
||||
saveResultsData,
|
||||
[client, results]);
|
||||
listenForResults.setCallbacks([resultsDataCallback]);
|
||||
// Listen for javascript custom notifications emitted by the View.
|
||||
const listenForViewNotification = new ClientEventListener('notify-client',
|
||||
recieveViewNotification);
|
||||
const getResultsCallback = new ListenerCallback('get-results',
|
||||
getResultsData,
|
||||
[client, results]);
|
||||
listenForViewNotification.setCallbacks([getResultsCallback]);
|
||||
client.setSocketEventListeners([listenForConnected,
|
||||
listenForQueryStatus,
|
||||
listenForQueryData,
|
||||
listenForMetaData,
|
||||
listenForViewNotification,
|
||||
listenForResults]);
|
||||
// Load the listeners so that they will be executed if triggered
|
||||
client.loadSocketEventListeners();
|
||||
/**
|
||||
* 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([
|
||||
'.pagination',
|
||||
'#display-options-form-expert_mode',
|
||||
'#display-options-form-result_context',
|
||||
'#display-options-form-results_per_page',
|
||||
'#download-results-json',
|
||||
'#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-download-modal', {}],
|
||||
'#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',
|
||||
'#export-full-inspect-context',
|
||||
]);
|
||||
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 listenForExportFullContextSwitch = new ViewEventListener('export-full-context-switch',
|
||||
exportFullContextSwitch,
|
||||
args);
|
||||
const listenForCreateFullResults = new ViewEventListener('create-full-results',
|
||||
createFullResults,
|
||||
args);
|
||||
const listenForCreateSubResults = new ViewEventListener('create-sub-results',
|
||||
createSubResults,
|
||||
args);
|
||||
const listenForExportFullResults = new ViewEventListener('export-full-results',
|
||||
exportFullResults,
|
||||
args);
|
||||
const listenForExportSubResults = new ViewEventListener('export-sub-results',
|
||||
exportSubResults,
|
||||
args);
|
||||
const listenForExportSingleMatch = new ViewEventListener('export-single-match',
|
||||
exportSingleMatch,
|
||||
args);
|
||||
// Set and load defined listeners
|
||||
resultsList.setViewEventListeners([
|
||||
listenForClientNotification,
|
||||
listenForPageNavigation,
|
||||
listenForExpertModeSwitch,
|
||||
listenForActionButtons,
|
||||
listenForDisplayOptions,
|
||||
listenForShowMetaData,
|
||||
listenForShowCorpusFiles,
|
||||
listenForExportFullContextSwitch,
|
||||
listenForCreateFullResults,
|
||||
listenForCreateSubResults,
|
||||
listenForExportFullResults,
|
||||
listenForExportSubResults,
|
||||
listenForExportSingleMatch,
|
||||
]);
|
||||
resultsList.loadViewEventListeners();
|
||||
// Connect client to server.
|
||||
client.notifyView('connecting');
|
||||
client.connect();
|
||||
// Send a query and recieve its answer data.
|
||||
let queryFormElement = document.querySelector('#query-form');
|
||||
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 e.g.: 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.
|
||||
*/
|
||||
let firstPageElement = document.querySelector('a.page');
|
||||
firstPageElement.click();
|
||||
} catch (e) {
|
||||
// No page element is present if first query is submitted.
|
||||
}
|
||||
// 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);
|
||||
});
|
||||
// Enable scroll to Top functionality.
|
||||
scrollToTop('header', '#menu-scroll-to-top-div');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
125
app/templates/corpora/corpus.html.j2
Normal file
125
app/templates/corpora/corpus.html.j2
Normal file
@ -0,0 +1,125 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12" data-corpus-id="{{ corpus.id }}" data-user-id="{{ corpus.creator.id }}" id="corpus-display">
|
||||
<div class="row">
|
||||
<div class="col s8 m9 l10">
|
||||
<h1 id="title"><span class="corpus-title"></span></h1>
|
||||
</div>
|
||||
<div class="col s4 m3 l2 right-align">
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<span class="chip status status-color status-text white-text"></span>
|
||||
<div class="active preloader-wrapper small status-spinner">
|
||||
<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>
|
||||
|
||||
<div class="card service-color-border border-darken" data-service="corpus-analysis" style="border-top: 10px solid">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<input class="corpus-description" disabled id="corpus-description" type="text">
|
||||
<label for="corpus-description">Description</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="input-field">
|
||||
<input class="corpus-creation-date validate" disabled id="corpus-creation-date" type="text">
|
||||
<label for="corpus-creation-date">Creation date</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="input-field">
|
||||
<input class="corpus-last-edited-date validate" disabled id="corpus-last-edited-date" type="text">
|
||||
<label for="corpus-last-edited-date">Last edited</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="input-field">
|
||||
<input class="corpus-token-ratio validate" disabled id="corpus-token-ratio" type="text">
|
||||
<label for="corpus-token-ratio">Nr. of tokens used <sup><i class="material-icons tooltipped tiny" data-position="bottom" data-tooltip="Current number of tokens in this corpus. Updates after every analyze session.">help</i></sup></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="analyse-corpus-trigger btn disabled waves-effect waves-light" href="{{ url_for('corpora.analyse_corpus', corpus_id=corpus.id) }}"><i class="material-icons left">search</i>Analyze</a>
|
||||
<a class="btn build-corpus-trigger disabled waves-effect waves-light" href="{{ url_for('corpora.prepare_corpus', corpus_id=corpus.id) }}"><i class="nopaque-icons left">K</i>Build</a>
|
||||
<a class="btn disabled export-corpus-trigger waves-effect waves-light"><i class="material-icons left">import_export</i>Export</a>
|
||||
<a class="btn modal-trigger red waves-effect waves-light" data-target="delete-corpus-modal"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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 <span class="corpus-title"></span>? All files will be permanently deleted!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn modal-close waves-effect waves-light" href="#!">Cancel</a>
|
||||
<a class="btn modal-close red waves-effect waves-light" href="{{ url_for('corpora.delete_corpus', corpus_id=corpus.id) }}"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="corpus-files" data-corpus-id="{{ corpus.id }}" data-user-id="{{ corpus.creator.id }}">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title" id="files">Corpus files</span>
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input class="search" id="search-corpus-files" type="search"></input>
|
||||
<label for="search-corpus-files">Search corpus files</label>
|
||||
</div>
|
||||
<table class="highlight responsive-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort" data-sort="filename">Filename</th>
|
||||
<th class="sort" data-sort="author">Author</th>
|
||||
<th class="sort" data-sort="title">Title</th>
|
||||
<th class="sort" data-sort="publishing-year">Publishing year</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
nopaque.appClient.loadUser({{ corpus.creator.id }});
|
||||
let corpusDisplay = new CorpusDisplay(document.querySelector('#corpus-display'));
|
||||
let corpusFileList = new CorpusFileList(document.querySelector('#corpus-files'));
|
||||
</script>
|
||||
{% endblock scripts %}
|
51
app/templates/corpora/corpus_file.html.j2
Normal file
51
app/templates/corpora/corpus_file.html.j2
Normal file
@ -0,0 +1,51 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ corpus_file.author }}: {{ corpus_file.title }} ({{ corpus_file.publishing_year }})</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.author, data_length='255', material_icon='person') }}
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.title, data_length='255', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.publishing_year, material_icon='access_time') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(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 form
|
||||
if field.short_name not in ['author', 'csrf_token', 'publishing_year', 'submit', 'title'] %}
|
||||
{{ wtf.render_field(field, data_length='255', material_icon=field.label.text[0:1]) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
58
app/templates/corpora/import_corpus.html.j2
Normal file
58
app/templates/corpora/import_corpus.html.j2
Normal file
@ -0,0 +1,58 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<p>Fill out the following form to import a corpus.</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">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.title, data_length='32', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 m8">
|
||||
{{ wtf.render_field(form.description, data_length='255', material_icon='description') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
{{ wtf.render_field(form.file, accept='.zip', placeholder='Choose your exported .zip file') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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 %}
|
30
app/templates/corpora/interactions/analysis.html.j2
Normal file
30
app/templates/corpora/interactions/analysis.html.j2
Normal file
@ -0,0 +1,30 @@
|
||||
<!-- WIP. The user should be able to call several analysis tools from here.-->
|
||||
|
||||
<div class="col s12 m3 l2" id="anlysis">
|
||||
<h6 style="margin-top: 0px;">Analysis</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<button id="placeholder1"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
disabled
|
||||
flat-interaction"
|
||||
type="submit">Action One
|
||||
<i class="material-icons left">cloud</i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<button id="placeholder2"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
disabled
|
||||
flat-interaction"
|
||||
type="submit">Action Two
|
||||
<i class="material-icons left">add</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
30
app/templates/corpora/interactions/cite.html.j2
Normal file
30
app/templates/corpora/interactions/cite.html.j2
Normal file
@ -0,0 +1,30 @@
|
||||
<!-- WIP. The user should be able to cite nopaque and the current service easily using these buttons.-->
|
||||
|
||||
<div class="col s12 m3 l2" id="cite">
|
||||
<h6 style="margin-top: 0px;">Cite Nopaque</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<button id="placeholder1"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
disabled
|
||||
flat-interaction"
|
||||
type="submit">Action One
|
||||
<i class="material-icons left">cloud</i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<button id="placeholder2"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
disabled
|
||||
flat-interaction"
|
||||
type="submit">Action Two
|
||||
<i class="material-icons left">add</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
24
app/templates/corpora/interactions/create.html.j2
Normal file
24
app/templates/corpora/interactions/create.html.j2
Normal file
@ -0,0 +1,24 @@
|
||||
<!-- HTML to allow the user to create sub results from the current query
|
||||
results.-->
|
||||
|
||||
<div class="col s12 m3 l2" id="create">
|
||||
<h6 style="margin-top: 0px;">Create</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<p>Add matches to Sub-Results with the
|
||||
<i class="material-icons tiny">add</i>
|
||||
button in the list or inspect view.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<p><span id="nr-marked-matches"></span> matches added for sub-results:</p>
|
||||
<textarea id="sub-results-indexes-display"
|
||||
class="materialize-textarea"
|
||||
disabled>
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
30
app/templates/corpora/interactions/display.html.j2
Normal file
30
app/templates/corpora/interactions/display.html.j2
Normal file
@ -0,0 +1,30 @@
|
||||
{% 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">
|
||||
{{ wtf.render_field(display_options_form.results_per_page,
|
||||
material_icon='format_list_numbered') }}
|
||||
{{ wtf.render_field(display_options_form.result_context,
|
||||
material_icon='short_text') }}
|
||||
<div class="col s12" style="line-height: 38px;">
|
||||
<div class="col s8">
|
||||
{{ display_options_form.expert_mode.label.text }}
|
||||
</div>
|
||||
<div class="class col s4 right-align">
|
||||
<div class="switch">
|
||||
<label style="margin-left: -20px;">
|
||||
{{ display_options_form.expert_mode() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
79
app/templates/corpora/interactions/export.html.j2
Normal file
79
app/templates/corpora/interactions/export.html.j2
Normal file
@ -0,0 +1,79 @@
|
||||
<!-- HTML to allow the user to export the current querey results in full or
|
||||
the selected sub results.-->
|
||||
|
||||
<div class="col s12 m3 l2" id="export">
|
||||
<h6 style="margin-top: 0px;">Export</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="row">
|
||||
<div class="col s12" style="line-height: 38px;">
|
||||
<div class="col s8">
|
||||
Full context
|
||||
<a class="tooltipped black-text" data-tooltip="Check this switch to
|
||||
create results for the download with full context. Creating
|
||||
results like this will take much longer but you will be able to
|
||||
inspect your matches in detail when you import them into the query
|
||||
results viewer.">
|
||||
<i class="material-icons tiny">info_outline</i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="class col s4 right-align">
|
||||
<div class="switch">
|
||||
<label style="margin-left: -20px;">
|
||||
<input type="checkbox" id="export-full-inspect-context">
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<button class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
disabled
|
||||
flat-interaction"
|
||||
type="submit"
|
||||
id="full-results-create">Create Results
|
||||
<i class="material-icons left">build</i>
|
||||
</button>
|
||||
<button id="full-results-export"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
hide
|
||||
flat-interaction"
|
||||
type="submit">Results
|
||||
<i class="material-icons left">file_download</i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<div class="progress hide" id="full-results-progress-bar">
|
||||
<div class="determinate"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<button class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
disabled
|
||||
flat-interaction"
|
||||
type="submit"
|
||||
id="sub-results-create">Create Sub-Results
|
||||
<i class="material-icons left">build</i>
|
||||
</button>
|
||||
<button id="sub-results-export"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
hide
|
||||
flat-interaction"
|
||||
type="submit">Sub-Results
|
||||
<i class="material-icons left">file_download</i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<div class="progress hide" id="sub-results-progress-bar">
|
||||
<div class="determinate"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
59
app/templates/corpora/interactions/infos.html.j2
Normal file
59
app/templates/corpora/interactions/infos.html.j2
Normal file
@ -0,0 +1,59 @@
|
||||
<!-- HTML for showing infos about the current query or result. Also gives
|
||||
the user the abiltiy to access the meta data for the current query or
|
||||
result.-->
|
||||
|
||||
<div class="col s12 m3 l2" id="infos">
|
||||
<h6 style="margin-top: 0px;">Infos</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="row">
|
||||
<div class="col s12"
|
||||
style="height: 39px;
|
||||
margin-top: 0px;
|
||||
padding-top: 5px;
|
||||
padding-left: 1.75rem;">
|
||||
<span id="loading-matches"
|
||||
class="black-text">
|
||||
<i class="material-icons left">dvr</i>
|
||||
<span id="recieved-match-count"></span>/
|
||||
<span id="total-match-count"></span>
|
||||
matches loaded
|
||||
</span>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<div class="progress hide" id="query-progress-bar">
|
||||
<div class="determinate"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<button id="show-meta-data"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
flat-interaction"
|
||||
type="submit">Corpus Meta Data
|
||||
<i class="material-icons left">info_outline</i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<button id="show-corpus-files"
|
||||
class="waves-effect
|
||||
waves-light
|
||||
btn-flat
|
||||
flat-interaction"
|
||||
type="submit">
|
||||
<i class="material-icons left">info_outline</i>
|
||||
Matches in
|
||||
<span id="text-lookup-count"></span>
|
||||
files
|
||||
</button>
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<p class="hide" id="query-results-user-feedback">
|
||||
<i class="material-icons tiny">help</i>
|
||||
Server is sending your results.
|
||||
Functions like "Export Results" and "Match Inspect" will be
|
||||
available after all matches have been loaded.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
5
app/templates/corpora/interactions/scroll_to_top.html.j2
Normal file
5
app/templates/corpora/interactions/scroll_to_top.html.j2
Normal file
@ -0,0 +1,5 @@
|
||||
<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 corpus-analysis-color.lighten">
|
||||
<i class="material-icons">arrow_upward</i>
|
||||
</a>
|
||||
</div>
|
12
app/templates/corpora/query_results/_breadcrumbs.html.j2
Normal file
12
app/templates/corpora/query_results/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,12 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('main.dashboard', _anchor='query-results') }}" target="_self">My query results</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('.add_query_result') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.add_query_result') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.query_result', query_result_id=query_result.id) %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.query_result', query_result_id=query_result.id) }}" target="_self">{{ query_result.title }}</a></li>
|
||||
{% elif request.path == url_for('.inspect_query_result', query_result_id=query_result.id) %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.inspect_query_result', query_result_id=query_result.id) }}" target="_self">{{ title }}</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
56
app/templates/corpora/query_results/add_query_result.html.j2
Normal file
56
app/templates/corpora/query_results/add_query_result.html.j2
Normal file
@ -0,0 +1,56 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/query_results/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<p>Fill out the following form to upload and view your exported query data from the corpus analsis.</p>
|
||||
<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">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
{{ wtf.render_field(form.title, data_length='32', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 m8">
|
||||
{{ wtf.render_field(form.description, data_length='255', material_icon='description') }}
|
||||
</div>
|
||||
<div class="col s12">
|
||||
{{ wtf.render_field(form.file, accept='.json', placeholder='Choose your .json file') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</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 %}
|
241
app/templates/corpora/query_results/inspect.html.j2
Normal file
241
app/templates/corpora/query_results/inspect.html.j2
Normal file
@ -0,0 +1,241 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/query_results/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<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 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" 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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# 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:
|
||||
* Document content is loaded and scripts are being imported and executed.
|
||||
*/
|
||||
|
||||
// Import Client classes. Client handles the server client communication.
|
||||
import {
|
||||
Client,
|
||||
ClientEventListener,
|
||||
ListenerCallback,
|
||||
} from '../../../static/js/modules/corpus_analysis/client/Client.js';
|
||||
/**
|
||||
* Import Client listener functions which will listen for defined socket or
|
||||
* javascript events.
|
||||
*/
|
||||
import {
|
||||
recieveQueryStatus,
|
||||
recieveQueryData,
|
||||
} from '../../../static/js/modules/corpus_analysis/client/listeners.js';
|
||||
// Import client listener callbacks so they can be registered to the listeners.
|
||||
import {
|
||||
prepareQueryData,
|
||||
saveQueryData,
|
||||
} from '../../../static/js/modules/corpus_analysis/client/callbacks.js';
|
||||
// Import Results class which will be used to save results data of a query etc.
|
||||
import {
|
||||
Results,
|
||||
} from '../../../static/js/modules/corpus_analysis/model/Results.js';
|
||||
/**
|
||||
* Import the ResultsList which can be understood as a View class that handles
|
||||
* how the data from Results is represented to the user. The ViewEventListener
|
||||
* is used to register listener functions which listen for events emitred by
|
||||
* the Client.
|
||||
*/
|
||||
import {
|
||||
ResultsList,
|
||||
ViewEventListener,
|
||||
} from '../../../static/js/modules/corpus_analysis/view/ResultsView.js';
|
||||
// Import listener which will be registered to the ViewEventListener class.
|
||||
import {
|
||||
// listener listening for client dispatched 'notify-vie' custom event.
|
||||
recieveClientNotification,
|
||||
// vanilla javascript Event listeners which are listening for button clicks.
|
||||
pageNavigation,
|
||||
expertModeSwitch,
|
||||
actionButtons,
|
||||
displayOptions,
|
||||
showMetaData,
|
||||
showCorpusFiles,
|
||||
} from '../../../static/js/modules/corpus_analysis/view/listeners.js';
|
||||
import {
|
||||
scrollToTop,
|
||||
} from '../../../static/js/modules/corpus_analysis/view/scrollToTop.js'
|
||||
/**
|
||||
* Second Phase:
|
||||
* Asynchronus and event driven code.
|
||||
*/
|
||||
/**
|
||||
* 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,
|
||||
[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);
|
||||
// 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 %}
|
131
app/templates/corpora/query_results/query_result.html.j2
Normal file
131
app/templates/corpora/query_results/query_result.html.j2
Normal file
@ -0,0 +1,131 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "corpora/query_results/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<p>Below the metadata for the results from the Corpus
|
||||
<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 }}">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 %}
|
||||
</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>
|
||||
|
||||
<div id="modal-text-details" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4>Bibliographic data</h4>
|
||||
<p id="bibliographic-data"></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<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");
|
||||
for (var btn of moreTextDetailsButtons) {
|
||||
btn.onclick = () => {
|
||||
let modal = document.getElementById("modal-text-details");
|
||||
modal = M.Modal.init(modal, {"dismissible": true});
|
||||
modal.open();
|
||||
let metadataKey = event.target.dataset.metadataKey;
|
||||
let textKey = event.target.dataset.textKey;
|
||||
let textData = {{ query_result.query_metadata|tojson|safe }}[metadataKey][textKey];
|
||||
console.log(textData);
|
||||
let bibliographicData = document.getElementById("bibliographic-data");
|
||||
bibliographicData.innerHTML = "";
|
||||
let table = document.createElement("table");
|
||||
for (let [key, value] of Object.entries(textData)) {
|
||||
table.insertAdjacentHTML("afterbegin",
|
||||
`
|
||||
<tr>
|
||||
<td>${key}</td>
|
||||
<td>${value}</td>
|
||||
</tr>
|
||||
`);
|
||||
}
|
||||
table.insertAdjacentHTML("afterbegin",
|
||||
`
|
||||
<thead>
|
||||
<th>Description</th>
|
||||
<th>Value</th>
|
||||
</thead>
|
||||
`)
|
||||
bibliographicData.appendChild(table);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
19
app/templates/errors/403.html.j2
Normal file
19
app/templates/errors/403.html.j2
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "base.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<p class="light">{{ request.path }}</p>
|
||||
<p>Alternatively, you can visit the <a href="{{ url_for('main.index') }}">Main Page</a> or read <a class="modal-trigger" href="#more-information-modal">more information</a> about this type of error.</p>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="more-information-modal">
|
||||
<div class="modal-content">
|
||||
<h2>About the "{{ title }}" error</h2>
|
||||
<p>The request contained valid data and was understood by the server, but the server is refusing action. This may be due to the user not having the necessary permissions for a resource or needing an account of some sort, or attempting a prohibited action (e.g. creating a duplicate record where only one is allowed). This code is also typically used if the request provided authentication by answering the WWW-Authenticate header field challenge, but the server did not accept that authentication. The request should not be repeated.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="btn-flat modal-close waves-effect waves-green">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
19
app/templates/errors/404.html.j2
Normal file
19
app/templates/errors/404.html.j2
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "base.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<p class="light">{{ request.path }}</p>
|
||||
<p>Alternatively, you can visit the <a href="{{ url_for('main.index') }}">Main Page</a> or read <a class="modal-trigger" href="#more-information-modal">more information</a> about this type of error.</p>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="more-information-modal">
|
||||
<div class="modal-content">
|
||||
<h2>About the "{{ title }}" error</h2>
|
||||
<p>The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="btn-flat modal-close waves-effect waves-green">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
19
app/templates/errors/413.html.j2
Normal file
19
app/templates/errors/413.html.j2
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "base.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<p class="light">{{ request.path }}</p>
|
||||
<p>Alternatively, you can visit the <a href="{{ url_for('main.index') }}">Main Page</a> or read <a class="modal-trigger" href="#more-information-modal">more information</a> about this type of error.</p>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="more-information-modal">
|
||||
<div class="modal-content">
|
||||
<h2>About the "{{ title }}" error</h2>
|
||||
<p>The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="btn-flat modal-close waves-effect waves-green">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
19
app/templates/errors/500.html.j2
Normal file
19
app/templates/errors/500.html.j2
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "base.html.j2" %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
<p class="light">{{ request.path }}</p>
|
||||
<p>Alternatively, you can visit the <a href="{{ url_for('main.index') }}">Main Page</a> or read <a class="modal-trigger" href="#more-information-modal">more information</a> about this type of error.</p>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="more-information-modal">
|
||||
<div class="modal-content">
|
||||
<h2>About the "{{ title }}" error</h2>
|
||||
<p>A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="btn-flat modal-close waves-effect waves-green">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
8
app/templates/jobs/_breadcrumbs.html.j2
Normal file
8
app/templates/jobs/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,8 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" target="_self">My jobs</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('.job', job_id=job.id) %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.job', job_id=job.id) }}" target="_self">{{ job.title }}</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
176
app/templates/jobs/job.html.j2
Normal file
176
app/templates/jobs/job.html.j2
Normal file
@ -0,0 +1,176 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "jobs/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="{{ job.service }}"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12" data-job-id="{{ job.id }}" data-user-id="{{ job.creator.id }}" id="job-display">
|
||||
<div class="row">
|
||||
<div class="col s8 m9 l10">
|
||||
<h1 id="title">[<span class="job-service"></span>] <span class="job-title"></span></h1>
|
||||
</div>
|
||||
<div class="col s4 m3 l2 right-align">
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
<span class="chip status status-text status-color white-text"></span>
|
||||
<div class="active preloader-wrapper small status-spinner">
|
||||
<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>
|
||||
|
||||
<div class="card service-color-border border-darken" data-service="{{ job.service }}" style="border-top: 10px solid">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="input-field">
|
||||
<input class="job-description" disabled id="job-description" type="text">
|
||||
<label for="job-description">Description</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="input-field">
|
||||
<input class="job-creation-date" disabled id="job-creation-date" type="text">
|
||||
<label for="job-creation-date">Creation date</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="input-field">
|
||||
<input class="job-end-date" disabled id="job-end-date" type="text">
|
||||
<label for="job-end-date">End date</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<div class="input-field">
|
||||
<input class="job-service" disabled id="job-service" type="text">
|
||||
<label for="job-service">Service</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<div class="input-field">
|
||||
<input class="job-service-args" disabled id="job-service-args" type="text">
|
||||
<label for="job-service-args">Service arguments</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<div class="input-field">
|
||||
<input class="job-service-version" disabled id="job-service-version" type="text">
|
||||
<label for="job-service-version">Service version</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{% if current_user.is_administrator() %}
|
||||
<a class="btn hide modal-trigger restart-job-trigger waves-effect waves-light" data-target="restart-job-modal"><i class="material-icons left">repeat</i>Restart</a>
|
||||
{% endif %}
|
||||
<!-- <a href="#" class="btn disabled waves-effect waves-light"><i class="material-icons left">settings</i>Export Parameters</a> -->
|
||||
<a class="btn modal-trigger red waves-effect waves-light" data-target="delete-job-modal"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="delete-job-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Confirm deletion</h4>
|
||||
<p>Do you really want to delete the job <span class="job-title"></span>? All associated files 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('jobs.delete_job', job_id=job.id) }}"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if current_user.is_administrator() %}
|
||||
<div id="restart-job-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Confirm restart</h4>
|
||||
<p>Do you really want to restart the job <span class="job-title"></span>? All log and result files 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('jobs.restart', job_id=job.id) }}"><i class="material-icons left">restart</i>Restart</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="job-inputs" data-job-id="{{ job.id }}" data-user-id="{{ job.creator.id }}">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12 m2">
|
||||
<span class="card-title"><i class="left material-icons" style="font-size: inherit;">input</i>Inputs</span>
|
||||
<p>Original input files.</p>
|
||||
</div>
|
||||
<div class="col s12 m10">
|
||||
<table class="highlight responsive-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort" data-sort="filename">Filename</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="job-results" data-job-id="{{ job.id }}" data-user-id="{{ job.creator.id }}">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12 m2">
|
||||
<span class="card-title"><i class="left material-icons" style="font-size: inherit;">done</i>Results</span>
|
||||
<p>Processed result files.</p>
|
||||
</div>
|
||||
<div class="col s12 m10">
|
||||
<table class="highlight responsive-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th>Filename</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
nopaque.appClient.loadUser({{ job.creator.id }});
|
||||
let jobDisplay = new JobDisplay(document.querySelector('#job-display'));
|
||||
let jobInputList = new JobInputList(document.querySelector('#job-inputs'));
|
||||
let jobResultList = new JobResultList(document.querySelector('#job-results'));
|
||||
</script>
|
||||
{% endblock scripts %}
|
14
app/templates/main/_breadcrumbs.html.j2
Normal file
14
app/templates/main/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,14 @@
|
||||
{% set breadcrumbs %}
|
||||
{% if not (request.path == url_for('.index')) %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% endif %}
|
||||
{% if request.path == url_for('.about_and_faq') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.about_and_faq') }}" target="_self">About and faq</a></li>
|
||||
{% elif request.path == url_for('.dashboard') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.dashboard') }}" target="_self">Dashboard</a></li>
|
||||
{% elif request.path == url_for('.news') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.news') }}" target="_self">News</a></li>
|
||||
{% elif request.path == url_for('.terms_of_use') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.terms_of_use') }}" target="_self">Terms of use</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
266
app/templates/main/about_and_faq.html.j2
Normal file
266
app/templates/main/about_and_faq.html.j2
Normal file
@ -0,0 +1,266 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">What is nopaque</span>
|
||||
<p>
|
||||
Our web application nopaque combines coordinated tools such as Optical
|
||||
Character Recognition (OCR), Natrual Language Processing (NLP) and a
|
||||
powerful Keyword In Context Search (KWIC) with the CQP query language.
|
||||
</p>
|
||||
<br>
|
||||
<p>
|
||||
nopaque offers the possibility to use all tools individually or as a
|
||||
workflow. All work steps are coordinated in such a way that individual
|
||||
services can be used on top of each other. The platform supports
|
||||
researchers in converting their files into formats that can be further
|
||||
processed, automatically enriching them with information and then
|
||||
analyzing them, so that nopaque maps a large part of the research
|
||||
processes in the humanities. With this toolbox we address researchers
|
||||
in the humanities from all disciplines and levels of knowledge.
|
||||
The data generated during the processes can be downloaded after each
|
||||
step in order to evaluate or further process them with other (external) tools.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<ul class="collapsible">
|
||||
<li>
|
||||
<div class="collapsible-header">1. Who is developing nopaque?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
<em>nopaque</em> is developed by a small, interdisciplinary Team at
|
||||
<em>University Bielefeld</em> called <em>Data Infrastructure and
|
||||
Digital Humanities (INF)</em>. We are part of the <em>SFB 1288 -
|
||||
Practices of comparing. Ordering and changing the world</em>.
|
||||
</p>
|
||||
<p>For mor information <a href="https://www.uni-bielefeld.de/(en)/sfb1288/">
|
||||
visit the SFB1288 web site</a> or
|
||||
<a href="https://www.uni-bielefeld.de/(en)/sfb1288/projekte/inf.html">
|
||||
our team page</a>.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">2. Is nopaque free to use for everyone?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
Yes nopaque is free to use for everyone! It does not matter if you
|
||||
are a researcher in the humanities, a student or just someone who
|
||||
wants to learn something new. Just <a href="http://nopaque.localhost/auth/register">
|
||||
sign up for it</a> and try it out!
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">3. How much does it cost to use nopaque?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>nopaque and the services provided by it are free of charge.</span>
|
||||
</div>
|
||||
<li>
|
||||
<li>
|
||||
<div class="collapsible-header">4. Why is nopaque written in lower case?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>We just think that nopaque with a lower case first letter looks
|
||||
better than Nopaque with an upper case first letter. Simple as that!
|
||||
</span>
|
||||
</div>
|
||||
<li>
|
||||
<li>
|
||||
<div class="collapsible-header">5. Why the name nopaque?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
When we started developing nopaque we wanted to have a cool name
|
||||
like <a href="https://voyant-tools.org/">voyant</a> which can be translated
|
||||
to light or seeing. So we choose opaque thinking that it means that
|
||||
something is transparent. After a while we realized that we misunderstood
|
||||
the meaning of the word (opaque means non-transparent) and simply
|
||||
negated it ending up with nopaque.
|
||||
</p>
|
||||
<p>
|
||||
We also think nopaque fits pretty nicley because we want you to be
|
||||
able to make your texts transparent and see through them with our
|
||||
analysis tool to gain knew knowledge about them.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
<li>
|
||||
<div class="collapsible-header">6. Is nopaque FOSS/Open Source?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>Yes nopaque only uses free and open source software (FOSS). You
|
||||
can find the <a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/opaque">
|
||||
source code in our gitlab repository</a>.
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">7. What software/technologies is nopaque using/build with?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
nopaques frontend (what the user sees) is written in HTML 5
|
||||
and Javascript. The backend (stuff that happens on our servers)
|
||||
is realized with <a href="https://palletsprojects.com/p/flask/">
|
||||
Flask</a>, a python based lightweight WSGI web application
|
||||
framework. We utilize <a href="https://www.docker.com/">Docker</a>
|
||||
to easily deploy nopaque on our servers.
|
||||
</p>
|
||||
<p>
|
||||
The client server real time comminication is implemented using
|
||||
<a href="https://flask-socketio.readthedocs.io/en/latest/">Flask-SocketIO</a>.
|
||||
</p>
|
||||
<p>Every service (e.g. OCR or NLP) provided by nopaque is using
|
||||
established opensource software. Take a look at their related
|
||||
questions to learn more about them.</p>
|
||||
<p>
|
||||
For more details take a look at the
|
||||
<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/opaque">source code</a>.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">8. What software/technology is used for the File Setup service?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
The File Setup service uses <a href="https://imagemagick.org/index.php">ImageMagick</a>
|
||||
to merge your images into one file.
|
||||
</p>
|
||||
<p>
|
||||
For more details take a look at the
|
||||
<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/file-setup">source code</a>.
|
||||
</p>
|
||||
</span>
|
||||
<li>
|
||||
<div class="collapsible-header">9. What software/technology is used for the OCR service?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
The OCR service uses <a href="https://github.com/tesseract-ocr/tesseract">Tesseract OCR.</a>
|
||||
</p>
|
||||
<p>
|
||||
For more details take a look at the
|
||||
<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/ocr">source code</a>.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">10. What software/technology is used for the NLP service?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
The NLP service uses <a href="https://spacy.io/">spaCy</a>.
|
||||
</p>
|
||||
<p>
|
||||
For more details take a look at the
|
||||
<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nlp">source code</a>.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">11. What software/technology is used for the Analysis service?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
The Corpus Analysis service uses the <a href="http://cwb.sourceforge.net/">
|
||||
IMS Open Corpus Workbench (CWB).</a> We developed a Python
|
||||
library for the IMS Open Corpus Workbench (CWB) corpus query
|
||||
interface (CQi) API to be able to request query results from the CWB
|
||||
server using simple Python code. The library is
|
||||
<a href="https://pypi.org/project/cqi/">avilable on PyPi.</a>
|
||||
</p>
|
||||
<p>
|
||||
For more details take a look at the
|
||||
<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/cqpweb">source code</a>.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
<li>
|
||||
<div class="collapsible-header">12. Can I download/export my results and processed files?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
Yes. You can download everything that is the result of a service
|
||||
and save it somwhere else. You can download your results depending
|
||||
on the service in easily reusable formats like TXT, PDF, JSON, XML
|
||||
and many more. This also empowers you to use your results in other
|
||||
third party software to continue you research beyond the capabiltiys
|
||||
of nopaque.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">13. Is my research data private?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
Your uploaded research data cannot be accessed by any third party.
|
||||
Take a look at our <a href="http://nopaque.localhost/privacy_policy">GDPR</a>
|
||||
statement and <a href="http://nopaque.localhost/terms_of_use">terms of use</a>
|
||||
if you want to learn more about how we handle your data.
|
||||
<p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">14. Could I use nopaque as a permant storage for my research data?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
nopaque saves your research data in theory as long as your account
|
||||
exists. But nopaque is not a cloud storage solution! We encourage
|
||||
you to permanently save your data somwhere else.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">15. What does OCR mean?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
OCR stands for Optical Character Recognition. OCR is the automatical
|
||||
conversion of images of handwritten or printed text into machine-encoded text.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="collapsible-header">16. What does NLP mean?</div>
|
||||
<div class="collapsible-body">
|
||||
<span>
|
||||
<p>
|
||||
NLP stands for natural language processing wich is a subfield of
|
||||
linguistics, computer science and artificial intelligence concerned
|
||||
with the interactions between computers and human language.
|
||||
For example nopaque uses spaCy to automtically tag every word with
|
||||
its part of speech tag which describes its grammatical property.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
182
app/templates/main/dashboard.html.j2
Normal file
182
app/templates/main/dashboard.html.j2
Normal file
@ -0,0 +1,182 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<h3>My Corpora and Query results</h3>
|
||||
<p>Create a corpus to interactively perform linguistic analysis or import query results to save interesting passages.</p>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<ul class="tabs">
|
||||
<li class="tab col s6"><a class="active" href="#corpora">Corpora</a></li>
|
||||
<li class="tab col s6"><a href="#query-results">Query results</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col s12" id="corpora">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-corpus" class="search" type="search"></input>
|
||||
<label for="search-corpus">Search corpus</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th><span class="sort" data-sort="status">Status</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="waves-effect waves-light btn" href="{{ url_for('corpora.import_corpus') }}"><i class="material-icons right">import_export</i>Import Corpus</a>
|
||||
<a class="waves-effect waves-light btn" href="{{ url_for('corpora.add_corpus') }}">New corpus<i class="material-icons right">add</i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12" id="query-results">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-query-results" class="search" type="search"></input>
|
||||
<label for="search-query-results">Search query result</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span> and<br>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th>
|
||||
<span class="sort" data-sort="corpus">Corpus</span> and<br>
|
||||
<span class="sort" data-sort="query">Query</span>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list">
|
||||
<tr class="show-if-only-child">
|
||||
<td colspan="5">
|
||||
<span class="card-title"><i class="material-icons left">folder</i>Nothing here...</span>
|
||||
<p>No query results yet imported.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="waves-effect waves-light btn" href="{{ url_for('corpora.add_query_result') }}">Add query result<i class="material-icons right">file_upload</i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="jobs">
|
||||
<h3>My Jobs</h3>
|
||||
<p>A job is the execution of a service provided by nopaque. You can create any number of jobs and let them be processed simultaneously.</p>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-job" class="search" type="search"></input>
|
||||
<label for="search-job">Search job</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span class="sort" data-sort="service">Service</span></th>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th><span class="sort" data-sort="status">Status</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<p><a class="modal-trigger waves-effect waves-light btn" href="#" data-target="new-job-modal"><i class="material-icons left">add</i>New job</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="new-job-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Select a service</h4>
|
||||
<p> </p>
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
<div class="card-panel center-align hoverable">
|
||||
<br>
|
||||
<a href="{{ url_for('services.service', service='file-setup') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text darken" data-service="file-setup"><b>File setup</b></p>
|
||||
<p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p>
|
||||
<a href="{{ url_for('services.service', service='file-setup') }}" class="waves-effect waves-light btn service-color darken" data-service="file-setup">Create Job</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="card-panel center-align hoverable">
|
||||
<br>
|
||||
<a href="{{ url_for('services.service', service='ocr') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="ocr" style="font-size: 2.5rem;"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text darken" data-service="ocr"><b>Optical Character Recognition</b></p>
|
||||
<p class="light">nopaque converts your image data – like photos or scans – into text data through a process called OCR. This step enables you to proceed with further computational analysis of your documents.</p>
|
||||
<a href="{{ url_for('services.service', service='ocr') }}" class="waves-effect waves-light btn service-color darken" data-service="ocr">Create Job</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="card-panel center-align hoverable">
|
||||
<br>
|
||||
<a href="{{ url_for('services.service', service='nlp') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="nlp" style="font-size: 2.5rem;"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text darken" data-service="nlp"><b>Natural Language Processing</b></p>
|
||||
<p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p>
|
||||
<a href="{{ url_for('services.service', service='nlp') }}" class="waves-effect waves-light btn service-color darken" data-service="nlp">Create Job</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-light btn-flat">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
let corpusList = new CorpusList(document.querySelector('#corpora'));
|
||||
let jobList = new JobList(document.querySelector('#jobs'));
|
||||
let queryResultList = new QueryResultList(document.querySelector('#query-results'));
|
||||
</script>
|
||||
{% endblock scripts %}
|
218
app/templates/main/index.html.j2
Normal file
218
app/templates/main/index.html.j2
Normal file
@ -0,0 +1,218 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="parallax-container" id="title">
|
||||
<div class="parallax">
|
||||
<img src="{{ url_for('static', filename='images/parallax_lq/01_books_antique_book_old.jpg') }}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section white scrollspy" id="information">
|
||||
<div class="row container">
|
||||
<div class="col s12 m10">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h3>Why you should use nopaque</h3>
|
||||
<p>nopaque is a custom-built web application for researchers who want to get out more of their images and texts without having to bother about the technical side of things. You can focus on what really interests you, nopaque does the rest.</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="row">
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<i class="large nopaque-icons secondary-color-text">A</i><br>
|
||||
<b class="primary-color-text">Speeds up your work</b>
|
||||
<p class="light">All tools provided by nopaque are carefully selected to provide a complete tool suite without being held up by compatibility issues.</p>
|
||||
</div>
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<i class="large nopaque-icons secondary-color-text">B</i><br>
|
||||
<b class="primary-color-text">Cloud infrastructure</b>
|
||||
<p class="light">All computational work is processed within nopaque’s cloud infrastructure. You don't need to install any software. Great, right?</p>
|
||||
</div>
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<i class="large nopaque-icons secondary-color-text">C</i><br>
|
||||
<b class="primary-color-text">User friendly</b>
|
||||
<p class="light">You can start right away without having to read mile-long manuals. All services come with default settings that make it easy for you to just get going. Also great, right?</p>
|
||||
</div>
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<i class="large nopaque-icons secondary-color-text">D</i><br>
|
||||
<b class="primary-color-text">Meshing processes</b>
|
||||
<p class="light">No matter where you step in, nopaque facilitates and accompanies your research. Its workflow perfectly ties in with your research process.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m2">
|
||||
<ul class="section table-of-contents">
|
||||
<li><a href="#information">Why you should use nopaque</a></li>
|
||||
<li><a href="#services">What nopaque can do for you</a></li>
|
||||
{% if current_user.is_anonymous %}
|
||||
<li><a href="#registration-and-log-in">Registration and log in</a></li>
|
||||
{% endif %}
|
||||
<li><a href="#workflow">Workflow</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="parallax-container">
|
||||
<div class="parallax">
|
||||
<img src="{{ url_for('static', filename='images/parallax_lq/02_concept_document_focus_letter.jpg') }}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section white scrollspy" id="services">
|
||||
<div class="row container">
|
||||
<div class="col s12 m10">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h3>What nopaque can do for you</h3>
|
||||
<p>All services and processes are logically linked and built upon each other. You can follow them step by step or directly choose the one that suits your needs best. And while the process is computed in nopaque’s cloud, you can just keep working.</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<div class="row">
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<a href="{{ url_for('services.service', service='file-setup') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text text-darken" data-service="file-setup"><b>File setup</b></p>
|
||||
<p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p>
|
||||
</div>
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<a href="{{ url_for('services.service', service='ocr') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="ocr"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text text-darken" data-service="ocr"><b>Optical Character Recognition</b></p>
|
||||
<p class="light">nopaque converts your image data – like photos or scans – into text data through OCR making it machine readable. This step enables you to proceed with further computational analysis of your documents.</p>
|
||||
</div>
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<a href="{{ url_for('services.service', service='nlp') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="nlp"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text text-darken" data-service="nlp"><b>Natural Language Processing</b></p>
|
||||
<p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p>
|
||||
</div>
|
||||
<div class="col s12 m6 l3 center-align">
|
||||
<a href="{{ url_for('services.service', service='corpus_analysis') }}" class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="corpus-analysis"></i>
|
||||
</a>
|
||||
<br><br>
|
||||
<p class="service-color-text text-darken" data-service="corpus-analysis"><b>Corpus analysis</b></p>
|
||||
<p class="light">nopaque lets you create and upload as many text corpora as you want. It makes use of CQP Query Language, which allows for complex search requests with the aid of metadata and NLP tags.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m2">
|
||||
<ul class="section table-of-contents">
|
||||
<li><a href="#information">Why you should use nopaque</a></li>
|
||||
<li><a href="#services">What nopaque can do for you</a></li>
|
||||
{% if current_user.is_anonymous %}
|
||||
<li><a href="#registration-and-log-in">Registration and log in</a></li>
|
||||
{% endif %}
|
||||
<li><a href="#workflow">Workflow</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="parallax-container">
|
||||
<div class="parallax">
|
||||
<img src="{{ url_for('static', filename='images/parallax_lq/03_text_data_wide.png') }}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if current_user.is_anonymous %}
|
||||
<div class="section white scrollspy" id="registration-and-log-in">
|
||||
<div class="row container">
|
||||
<div class="col s12 m10">
|
||||
<div class="row">
|
||||
<div class="col s12 m4">
|
||||
<h3>Registration and Log in</h3>
|
||||
<p>Want to boost your research and get going? nopaque is free and no download is needed. Register now!</p>
|
||||
<a class="btn waves-effect waves-light" href="{{ url_for('auth.register') }}"><i class="material-icons left">person_add</i>Register</a>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<br class="hide-on-small-only">
|
||||
<div class="card">
|
||||
<form method="POST">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Log in</span>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.user, material_icon='person') }}
|
||||
{{ wtf.render_field(form.password, material_icon='vpn_key') }}
|
||||
<div class="row" style="margin-bottom: 0;">
|
||||
<div class="col s6 left-align">
|
||||
<a href="{{ url_for('auth.reset_password_request') }}">Forgot your password?</a>
|
||||
</div>
|
||||
<div class="col s6 right-align">
|
||||
{{ wtf.render_field(form.remember_me) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m2">
|
||||
<ul class="section table-of-contents">
|
||||
<li><a href="#information">Why you should use nopaque</a></li>
|
||||
<li><a href="#services">What nopaque can do for you</a></li>
|
||||
{% if current_user.is_anonymous %}
|
||||
<li><a href="#registration-and-log-in">Registration and log in</a></li>
|
||||
{% endif %}
|
||||
<li><a href="#workflow">Workflow</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="parallax-container">
|
||||
<div class="parallax">
|
||||
<img src="{{ url_for('static', filename='images/parallax_lq/04_german_text_book_paper.jpg') }}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="section white scrollspy" id="workflow">
|
||||
<div class="row container">
|
||||
<!-- <div class="col s12 m10"> -->
|
||||
<div class="col s12">
|
||||
<h3>Workflow</h3>
|
||||
<p>Coming soon...</p>
|
||||
<!--<img src="{{ url_for('static', filename='images/workflow.png') }}" alt="Workflow" class="responsive-img">-->
|
||||
</div>
|
||||
<!--
|
||||
<div class="col s12 m2">
|
||||
<ul class="section table-of-contents">
|
||||
<li><a href="#information">Why you should use nopaque</a></li>
|
||||
<li><a href="#services">What nopaque can do for you</a></li>
|
||||
{% if current_user.is_anonymous %}
|
||||
<li><a href="#registration-and-log-in">Registration and log in</a></li>
|
||||
{% endif %}
|
||||
<li><a href="#workflow">Workflow</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="parallax-container">
|
||||
<div class="parallax">
|
||||
<img src="{{ url_for('static', filename='images/parallax_lq/05_chapter_book_text_tale.jpg') }}" alt="">
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
35
app/templates/main/news.html.j2
Normal file
35
app/templates/main/news.html.j2
Normal file
@ -0,0 +1,35 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card" id="nlp-removed-language-support">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Natural Language Processing removed language support</span>
|
||||
<p>Dear users</p>
|
||||
<br>
|
||||
<p>Not all language models support all features we utizlize in our NLP service. Thats why we had to drop them, as soon as they meet our requirements we will add them back!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card" id="beta-launch">
|
||||
<div class="card-content">
|
||||
<span class="card-title">nopaque's beta launch</span>
|
||||
<p>Dear users</p>
|
||||
<br>
|
||||
<p>A few days ago we went live with nopaque. Right now nopaque is still in its Beta phase. So some bugs are to be expected. If you encounter any bugs or some feature is not working as expected please send as an email using the feedback button at the botton of the page in the footer!</p>
|
||||
<p>We are happy to help you with any issues and will use the feedback to fix all mentioned bugs!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
155
app/templates/main/privacy_policy.html.j2
Normal file
155
app/templates/main/privacy_policy.html.j2
Normal file
@ -0,0 +1,155 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<p>With these data protection notices, Bielefeld University fulfils its obligation to provide information in accordance with Articles 13 & 14 of the EU General Data Protection Regulation (GDPR) on the above-mentioned processing of personal data. Terms such as "personal data", "processing", "data controller", "third party", etc. are used as defined in Article 4 GDPR.</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 1 Contact Details</span>
|
||||
<p>Bielefeld University, a legal entity under public law established by the state of North Rhine-Westphalia (NRW), is responsible for processing the data. It is represented by its rector, Prof. Dr. Ing. Gerhard Sagerer.</p>
|
||||
<h6>§ 1.1. Contact details of the data controller</h6>
|
||||
<ul class="browser-default">
|
||||
<li>Data protection officer of the Faculty of History</li>
|
||||
<li>Prof. Dr. Stefan Gorißen</li>
|
||||
<li>Universitätsstraße 25</li>
|
||||
<li>D-33615 Bielefeld</li>
|
||||
<li>Phone: +49 521 / 106-3152</li>
|
||||
<li>Email:
|
||||
<a href="mailto:stefan.gorissen@uni-bielefeld.de">stefan.gorissen@uni-bielefeld.de</a>
|
||||
</li>
|
||||
<li>Web:
|
||||
<a href="https://www.uni-bielefeld.de">https://www.uni-bielefeld.de</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h6>§ 1.2. Technical contact person</h6>
|
||||
<ul class="browser-default">
|
||||
<li>Dr. Johanna Vompras</li>
|
||||
<li>Email:
|
||||
<a href="mailto:johanna.vompras@uni-bielefeld.de">johanna.vompras@uni-bielefeld.de</a>
|
||||
</li>
|
||||
<li>Web.:
|
||||
<a href="https://www.uni-bielefeld.de/(en)/sfb1288/projekte/inf.html">https://www.uni-bielefeld.de/(en)/sfb1288/projekte/inf.html</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h6>§ 1.2. Contact details of the data protection officer</h6>
|
||||
<ul class="browser-default">
|
||||
<li>The data protection officer responsible is:</li>
|
||||
<li>Phone: +49 521 106-5225</li>
|
||||
<li>
|
||||
Email: <a href="mailto:datenschutzbeauftragte@uni-bielefeld.de">datenschutzbeauftragte@uni-bielefeld.de</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 2 General information on data processing and its purpose</span>
|
||||
<p>We process the personal data of our users only to the extent necessary to provide a functioning website and its functionalities.</p>
|
||||
<p>The following personal data is collected and stored within the system:</p>
|
||||
<h6>Master Data</h6>
|
||||
<p>Within the scope of user authentication the following personal data is collected and processed:</p>
|
||||
<ul class="browser-default">
|
||||
<li>User name</li>
|
||||
<li>E-Mail</li>
|
||||
</ul>
|
||||
<p>Registration of the user is required for the provision of certain content and services within nopaque.</p>
|
||||
<h6>Protocol Data</h6>
|
||||
<p>In general, when a website is visited, for technical reasons information is automatically sent from the browser to the server and stored there in access protocols. When using a web application, additional protocol data is also generated, which is necessary for tracking technical errors. This information includes:</p>
|
||||
<ul class="browser-default">
|
||||
<li>IP address</li>
|
||||
<li>User account</li>
|
||||
<li>Complete HTTP request URL</li>
|
||||
<li>HTTP action (e.g. GET: call up a page, POST: send form data)</li>
|
||||
<li>Access status (HTTP status code)</li>
|
||||
<li>data volume retrieved</li>
|
||||
<li>Date and time of the action</li>
|
||||
<li>User-Agent string</li>
|
||||
</ul>
|
||||
<p>Locally logged data will be used by the development team in order to debug and improve tools. This data can only be viewed by the technical administration and by the employees responsible for the nopaque platform. Data is stored for seven days to ensure proper technical operation and to find the cause of errors and is deleted <u>afterwards</u>.</p>
|
||||
<p>Logged data may be used to understand how researchers are using the nopaque platform. To be able to use the data for research purposes, we reserve the right to store it in an anonymous and aggregated form for a longer period of time (up to two years after completion of the SFB 1288 INF project).</p>
|
||||
<h6>Cookies</h6>
|
||||
<p>Browsers store so-called cookies. Cookies are files that can be stored by the provider of a website in the directory of the browser program on the user's computer. These files contain text information and can be read again by the provider when the page is called up again. The provider can use these cookies, for example, to always deliver pages in the theme selected by the user.</p>
|
||||
<p>The storage of cookies can be switched off in the browser settings or provided with an expiry time. By deactivating cookies, however, some functions that are controlled by cookies can then only be used to a limited extent or not at all.</p>
|
||||
<p>NOPAQUE uses cookies for the following purposes:</p>
|
||||
<ul class="browser-default">
|
||||
<li>Recognition of a user during a session in order to assign personal content and other user-defined settings.</li>
|
||||
<li>Login Script with ‘Remember Me’ feature allows the user to preserve their logged in status. When the user checks the Remember Me option, then the logged in status is serialized in the session and stored in cookies in an encrypted way.</li>
|
||||
</ul>
|
||||
<h6>Content Data</h6>
|
||||
<p>The content data includes all data that is entered or created by users themselves in the system. This data is listed here because it is assigned to individual authors and may contain personal data. This may include: uploaded files, images, texts or other media files. Please note that files and scans submitted to NOPAQUE are stored in order to allow persistent access during a work session and between work sessions.</p>
|
||||
<p>According to § 4 paragraph 2 of the General Terms of Use for the use of NOPAQUE at Bielefeld University, the users themselves are responsible for the content they post and must comply with the legal provisions of data protection. This includes in particular the deletion of personal data that may no longer be processed.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 3 Legal basis of the data processing</span>
|
||||
<p>The legal basis for the processing of personal data for user authentication is <b>Article 6 (1) letter e GDPR</b>. The processing is carried out within the framework of the fulfilment of the tasks of Bielefeld University in accordance with HG NRW (NRW Higher Education Act), if necessary in connection with an order of the university to be named or by a special law, e.g. University Statistics Act, State Civil Servants Act, Staff Representation Act, Equal Opportunities Act.</p>
|
||||
<p>The collection of personal data for user authentication is based on the consent of the data subjects as stated in <b>Article 6 (1) letter a GDPR</b>. The legal basis for the transmission of personal data is <b>Article 6 (1) letter c GDPR</b>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 4 Data transmissions</span>
|
||||
<p>Your personal data, which are processed by Bielefeld University for the purposes mentioned under 2. will not be transferred to third parties.</p>
|
||||
<p>In individual cases, data may also be legally transmitted to third parties, for example, to law enforcement authorities for the investigation of criminal offences within the framework of the <b>Code of Criminal Procedure (StPO)</b>. If technical service providers are given access to personal data, this is done on the basis of a contract in accordance with <b>Article 28 GDPR</b>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 5 Duration of processing / data deletion</span>
|
||||
<p>Data processed for user authentication are deleted immediately after account deletion.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 6 Your rights as a data subject</span>
|
||||
<p>As a data subject, you have certain rights under <b>GDPR</b> that you may assert at any time:</p>
|
||||
<ul class="browser-default">
|
||||
<li>the right to access information about whether or not personal data concerning you is processed, and if so, what categories of data are being processed (<b>Article 15 GDPR</b>),</li>
|
||||
<li>the right to demand the rectification or completion of data concerning you (<b>Article 16 GDPR</b>),</li>
|
||||
<li>the right to erasure of your personal data in accordance with <b>Article 17 GDPR</b>,</li>
|
||||
<li>the right to demand the restriction of the processing of your data per <b>Article 18 GDPR</b>,</li>
|
||||
<li>the right to withdraw your consent at any time. The withdrawal of consent does not affect the lawfulness of the processing based on consent before its withdrawal (<b>Article 7 (3) GDPR</b>),</li>
|
||||
<li>the right to object to the future processing of your data in accordance of <b>Article 21 GDPR</b>,</li>
|
||||
<li>the right to receive personal data concerning you and your account in a structured, common and machine-readable format in accordance of <b>Article 20 GDPR</b>.</li>
|
||||
</ul>
|
||||
<p>In addition to the aforementioned rights, you have the right to lodge a complaint with the data protection supervisory authority (<b>Article 77 GDPR</b>); for example, the university is under the supervision of the</p>
|
||||
<ul>
|
||||
<li>North Rhine-Westphalia State Commissioner</li>
|
||||
<li>for Data Protection and Freedom of Information</li>
|
||||
<li>(Landesbeauftragte für Datenschutz und</li>
|
||||
<li>Informationsfreiheit Nordrhein-Westfalen)</li>
|
||||
<li>Kavalleriestraße 2-4</li>
|
||||
<li>40213 Düsseldorf, German</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
112
app/templates/main/terms_of_use.html.j2
Normal file
112
app/templates/main/terms_of_use.html.j2
Normal file
@ -0,0 +1,112 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<p>With the usage of the nopaque platform you declare your acceptance of the General Terms of Use and that you have taken note of the legal framework and the data protection declaration.</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 1 Scope</span>
|
||||
<p>The General Terms of Use for the nopaque platform apply to everyone who uses the system as an authorised user in the sense of <b>§ 2</b> (1) of the General Terms of Use. By using the system and with your consent you accept these terms of use.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 2 Right of use</span>
|
||||
<p>(1) The nopaque platform is available to users exclusively for the purposes of teaching and research. Any other use, especially for business, commercial is not permitted. The following groups shall be entitled to use the nopaque platform:</p>
|
||||
<ul class="browser-default">
|
||||
<li>students, teaching staff and employees at Bielefeld University</li>
|
||||
<li>external researchers from outside the University Bielefeld</li>
|
||||
</ul>
|
||||
<p> </p>
|
||||
<p>(2) The use of the system is free of charge.</p>
|
||||
<p> </p>
|
||||
<p>(3) The duration of the right of use ends with the deletion of the user account by the user (see <b>§ 7</b>)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 3 Purpose of the Services</span>
|
||||
<p>nopaque custom-built web application which serves as a platform for preprocessing and analysing digital copies of various text based research data (books, letters, etc.) in different files and formats. nopaque converts image data – like photos or scans – into text data through OCR making it machine readable. This step enables to proceed with further computational analysis of the documents. By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from texts.</p>
|
||||
<p> </p>
|
||||
<p>(1) Change of service</p>
|
||||
<p>The provider of the nopaque platform is entitled to change and supplement the scope of functions of nopaque without prior notice. This could result from a thematic and scientific reorientation of the project.</p>
|
||||
<p> </p>
|
||||
<p>(2) Support</p>
|
||||
<p>On nopaque, a contact form is available. As far as possible the SFB 1288 INF staff will try to provide user support.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 4 Obligations of the User</span>
|
||||
<p>(1) The system is suitable for normal security requirements. Data with a high need for protection (e.g. health data) may not be stored or processed in the nopaque platform.</p>
|
||||
<p> </p>
|
||||
<p>(2) Users of nopaque are responsible for their own entered contents. The uploading of illegal content, especially content that violates criminal, personal, data protection or copyright regulations (including § 60a) is not permitted.</p>
|
||||
<p> </p>
|
||||
<p>(3) Users undertake to indemnify Bielefeld University from all claims by third parties based on the data they use and to reimburse Bielefeld University for any costs incurred by the latter due to possible infringements of rights. This also includes the costs incurred by Bielefeld University in defending itself against such claims in and out of court.</p>
|
||||
<p> </p>
|
||||
<p>(4) Exclusion from use</p>
|
||||
<p>Bielefeld University is entitled to immediately block access to the service if there are reasonable grounds to suspect that the stored data is unlawful (e.g upload harmful files via file upload) and/or violates the rights of third parties. Other infringements of the provisions of these Terms of Use, in particular the obligations under §6 also entitle Bielefeld University to block the user. Bielefeld University shall immediately notify the user of the block and the reason for the block. The block must be lifted as soon as the suspicion is invalidated.</p>
|
||||
<p> </p>
|
||||
<p>(5) Usage of Data</p>
|
||||
<p>The data stored by the user on the storage space intended for him may be legally protected, the responsibility for the processing of the data from these points of view lies solely with the user. By using nopaque, the user grants Bielefeld the right to process the data with the corresponding tools. At all times during processing in nopaque, data remains in the user's private storage location and will not passed on to third parties.</p>
|
||||
<p> </p>
|
||||
<p>(6) Release of Bielefeld University from Third-Party Claims</p>
|
||||
<p>The user is responsible for the data stored by him/her in nopaque. Furthermore he/she is responsible for entering and maintaining the data and information required to use nopaque.</p>
|
||||
<p> </p>
|
||||
<p>The user is obliged to indemnify Bielefeld University against all claims by third parties based on the data stored by him/her and to reimburse Bielefeld University for any costs incurred as a result of possible legal infringements. This also includes the costs incurred by Bielefeld University for extrajudicial and judicial defense against these claims.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 5 Liability of Bielefeld University</span>
|
||||
<p>Claims for damages against Bielefeld University are excluded irrespective of the legal grounds. Bielefeld University shall not be liable for loss of data and information or other „indirect“ damages, e.g. loss of profit, loss of production, or other indirect damages. Bielefeld University shall not be liable for the loss of data to the extent that the damage is due to the fact that the user has failed to back up the data and thereby ensure that lost data can be restored with justifiable effort.</p>
|
||||
<p> </p>
|
||||
<p>nopaque is available in accordance with normal operational care based on the "Best Effort" practice. No liability is assumed for the consequences of failures or errors of the nopaque platform. Bielefeld University does not guarantee that the systems will run error-free and without interruption at all times. Bielefeld University accepts no responsibility for technical quality. Nor is it liable for the content, in particular for the accuracy, completeness, and timeliness of information to which it merely provides access for use.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 6 Data Protection</span>
|
||||
<p>Information on the handling of personal data during the operation of the service can be found in the separate data protection policy.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">§ 7 Duration and Termination</span>
|
||||
<p>The user may terminate the use nopaque by deleting his/her account at any time without giving reasons. After deletion of the account, all users‘ data will be automatically deleted and access to the service blocked. This does not affect the user's right to delete data under data protection law.</p>
|
||||
<p> </p>
|
||||
<p>Bielefeld University may exclude the user from using the service without notice for an important reason. Important reasons include, in particular, repeated violations of the provisions of these Terms of Use or of applicable laws.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
45
app/templates/materialize/base.html.j2
Normal file
45
app/templates/materialize/base.html.j2
Normal file
@ -0,0 +1,45 @@
|
||||
{% block doc %}
|
||||
<!DOCTYPE html>
|
||||
<html{% block html_attribs %}{% endblock html_attribs %}>
|
||||
{% block html %}
|
||||
<head>
|
||||
{% block head %}
|
||||
<title>{% block title %}{{title|default}}{% endblock title %}</title>
|
||||
|
||||
{% block metas %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% endblock metas %}
|
||||
|
||||
{% block styles %}
|
||||
<link href="{{ url_for('static', filename='css/material_icons.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/materialize.min.css') }}" media="screen,projection" rel="stylesheet">
|
||||
{% endblock styles %}
|
||||
{% endblock head %}
|
||||
</head>
|
||||
<body{% block body_attribs %}{% endblock body_attribs %}>
|
||||
{% block body %}
|
||||
<header{% block header_attribs %}{% endblock header_attribs %}>
|
||||
{% block header %}
|
||||
{% block navbar %}
|
||||
{% endblock navbar %}
|
||||
{% block sidenav %}
|
||||
{% endblock sidenav %}
|
||||
{% endblock header %}
|
||||
</header>
|
||||
|
||||
<main{% block main_attribs %}{% endblock main_attribs %}>
|
||||
{% block main %}{% endblock main %}
|
||||
</main>
|
||||
|
||||
<footer{% block footer_attribs %}{% endblock footer_attribs %}>
|
||||
{% block footer %}{% endblock footer %}
|
||||
</footer>
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
|
||||
{% endblock scripts %}
|
||||
{% endblock body %}
|
||||
</body>
|
||||
{% endblock html %}
|
||||
</html>
|
||||
{% endblock doc %}
|
101
app/templates/materialize/wtf.html.j2
Normal file
101
app/templates/materialize/wtf.html.j2
Normal file
@ -0,0 +1,101 @@
|
||||
{% macro render_field(field) %}
|
||||
{% if field.type == 'BooleanField' %}
|
||||
{{ render_boolean_field(field, *args, **kwargs) }}
|
||||
{% elif field.type == 'DecimalRangeField' %}
|
||||
{{ render_decimal_range_field(field, *args, **kwargs) }}
|
||||
{% elif field.type == 'SubmitField' %}
|
||||
{{ render_submit_field(field, *args, **kwargs) }}
|
||||
{% elif field.type in ['FileField', 'MultipleFileField'] %}
|
||||
{{ render_file_field(field, *args, **kwargs) }}
|
||||
{% else %}
|
||||
{% if 'class_' in kwargs and 'validate' not in kwargs['class_'] %}
|
||||
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' validate'}) %}
|
||||
{% else %}
|
||||
{% set tmp = kwargs.update({'class_': 'validate'}) %}
|
||||
{% endif %}
|
||||
{{ render_generic_field(field, *args, **kwargs) }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_boolean_field(field) %}
|
||||
{% set label = kwargs.pop('label', True) %}
|
||||
<div class="switch">
|
||||
{% if 'material_icon' in kwargs %}
|
||||
<i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
|
||||
{% endif %}
|
||||
<label>
|
||||
{{ field(*args, **kwargs) }}
|
||||
<span class="lever"></span>
|
||||
{% if label %}
|
||||
{{ field.label.text }}
|
||||
{% endif %}
|
||||
</label>
|
||||
{% for error in field.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_file_field(field) %}
|
||||
{% set placeholder = kwargs.pop('placeholder', '') %}
|
||||
<div class="file-field input-field">
|
||||
<div class="btn">
|
||||
<span>{{ field.label.text }}</span>
|
||||
{{ field(*args, **kwargs) }}
|
||||
</div>
|
||||
<div class="file-path-wrapper">
|
||||
<input class="file-path validate" type="text" placeholder="{{ placeholder }}">
|
||||
</div>
|
||||
{% for error in field.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_generic_field(field) %}
|
||||
{% if field.type == 'TextAreaField' and 'materialize-textarea' not in kwargs['class_'] %}
|
||||
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' materialize-textarea'}) %}
|
||||
{% elif field.type == 'IntegerField' %}
|
||||
{% set tmp = kwargs.update({'type': 'number'}) %}
|
||||
{% endif %}
|
||||
{% set label = kwargs.pop('label', True) %}
|
||||
<div class="input-field">
|
||||
{% if 'material_icon' in kwargs %}
|
||||
<i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
|
||||
{% endif %}
|
||||
{{ field(*args, **kwargs) }}
|
||||
{% if label %}
|
||||
{{ field.label }}
|
||||
{% endif %}
|
||||
{% for error in field.errors %}
|
||||
<span class="helper-text red-text">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_submit_field(field) %}
|
||||
{% if 'class_' in kwargs and 'btn' not in kwargs['class_'] %}
|
||||
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' btn'}) %}
|
||||
{% else %}
|
||||
{% set tmp = kwargs.update({'class_': 'btn'}) %}
|
||||
{% endif %}
|
||||
{% if 'waves-effect' not in kwargs['class_'] %}
|
||||
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' waves-effect'}) %}
|
||||
{% endif %}
|
||||
{% if 'waves-light' not in kwargs['class_'] %}
|
||||
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' waves-light'}) %}
|
||||
{% endif %}
|
||||
<button class="{{ kwargs['class_'] }}"
|
||||
id="{{ field.id }}"
|
||||
name="{{ field.name }}"
|
||||
type="submit"
|
||||
value="{{ field.label.text }}"
|
||||
{% if 'style' in kwargs %}
|
||||
style="{{ kwargs.pop('style') }}"
|
||||
{% endif %}>
|
||||
{{ field.label.text }}
|
||||
{% if 'material_icon' in kwargs %}
|
||||
<i class="material-icons right">{{ kwargs.pop('material_icon') }}</i>
|
||||
{% endif %}
|
||||
</button>
|
||||
{% endmacro %}
|
15
app/templates/modals/analysis_init.html.j2
Normal file
15
app/templates/modals/analysis_init.html.j2
Normal file
@ -0,0 +1,15 @@
|
||||
<!-- Analysis init modal. User feedback showing that the analysis session is loading. -->
|
||||
<div class="modal no-autoinit" id="analysis-init-modal">
|
||||
<div class="modal-content">
|
||||
<h4>Initializing your corpus analysis session...</h4>
|
||||
<p>If the loading takes to long or an error occured,
|
||||
<a onclick="window.location.reload()" href="#">click here</a>
|
||||
to refresh your session or
|
||||
<a href="{{ url_for('corpora.corpus', corpus_id=corpus.id) }}">go back</a>!
|
||||
</p>
|
||||
<div id="analysis-init-progress" class="progress">
|
||||
<div class="indeterminate"></div>
|
||||
</div>
|
||||
<p id="analysis-init-error" class="hide red-text"></p>
|
||||
</div>
|
||||
</div>
|
75
app/templates/modals/context_modal.html.j2
Normal file
75
app/templates/modals/context_modal.html.j2
Normal file
@ -0,0 +1,75 @@
|
||||
<!-- Modal showing detailed context info for one match. -->
|
||||
<div id="context-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<form>
|
||||
<div class="row" style="margin-bottom: 0px; margin-top: -20px;">
|
||||
<div class="col s12 m6 l6">
|
||||
<div class="section">
|
||||
<h6 style="margin-top: 0px;">Display</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="col s12" style="margin-bottom: 10px;">
|
||||
{{ inspect_display_options_form.expert_mode_inspect.label.text }}
|
||||
<div class="switch right">
|
||||
<label>
|
||||
{{ inspect_display_options_form.expert_mode_inspect() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12" style="margin-bottom: 10px;">
|
||||
{{ inspect_display_options_form.highlight_sentences.label.text }}
|
||||
<div class="switch right">
|
||||
<label>
|
||||
{{ inspect_display_options_form.highlight_sentences() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12" style="margin-bottom: 10px;">
|
||||
Sentences around match
|
||||
<div class="input-field right" style="margin-top: -2rem;
|
||||
margin-bottom: -2rem;
|
||||
height: 0px;">
|
||||
<p class="range-field">
|
||||
<input type="range"
|
||||
id="context-sentences"
|
||||
min="1"
|
||||
max="10"
|
||||
value="3" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l6" id="create-from-inspect">
|
||||
<div class="section">
|
||||
<h6 style="margin-top: 0px;">Create</h6>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="col s12">
|
||||
Add to Sub Results
|
||||
<div class="secondary-content right" id="create-inspect-menu">
|
||||
{# The needed button is created and added via javascript #}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row section">
|
||||
<h5 style="margin-top: 0px;">Context for match:
|
||||
<span id="context-match-nr"></span></h5>
|
||||
<div class="divider" style="margin-bottom: 10px;"></div>
|
||||
<div class="col s12" >
|
||||
<div id="context-results">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a id="inspect-results-export" class="left waves-effect waves-light btn">
|
||||
Export Single 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>
|
52
app/templates/modals/export_query_results.html.j2
Normal file
52
app/templates/modals/export_query_results.html.j2
Normal file
@ -0,0 +1,52 @@
|
||||
<!-- Export query results modal. Allos the user to download the results in different file formats. WIP -->
|
||||
<div id="query-results-download-modal"
|
||||
class="modal modal-fixed-footer no-autoinit">
|
||||
<div class="modal-content">
|
||||
<h4>Download your results</h4>
|
||||
<p>Download your results or sub results in different file formats like JSON
|
||||
or CSV, so you can reuse them in Excel or other software.
|
||||
You can also simply publish your results as raw data using one of these
|
||||
formats. We recommend JSON!
|
||||
</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>
|
18
app/templates/modals/query_builder.html.j2
Normal file
18
app/templates/modals/query_builder.html.j2
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- Modal showing the corpus files for the current query results including title ant match count per corpus file. -->
|
||||
<div id="query-builder-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Query builder</h4>
|
||||
<p>Comming soon...</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="btn modal-close waves-effect waves-green btn" id="query-builder-submit">Done</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let queryBuilderSubmitElement = document.querySelector('#query-builder-submit');
|
||||
queryBuilderSubmitElement.addEventListener('click', () => {
|
||||
let queryElement = document.querySelector('#query-form-query');
|
||||
// queryElement.value = 'Inhalt';
|
||||
});
|
||||
</script>
|
17
app/templates/modals/show_corpus_files.html.j2
Normal file
17
app/templates/modals/show_corpus_files.html.j2
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- Modal showing the corpus files for the current query results including title ant match count per corpus file. -->
|
||||
<div id="show-corpus-files-modal" class="modal bottom-sheet">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="section">
|
||||
<div class="col s12 right-align">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn red"
|
||||
style="left: 5px;">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 modal-content" id="show-corpus-files-modal-content"></div>
|
||||
<div class="col s12 modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn red">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
17
app/templates/modals/show_metadata.html.j2
Normal file
17
app/templates/modals/show_metadata.html.j2
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- Modal showing the meta data for the current query results or the imported results -->
|
||||
<div id="meta-data-modal" class="modal bottom-sheet">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="section">
|
||||
<div class="col s12 right-align">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn red"
|
||||
style="left: 5px;">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 modal-content" id="meta-data-modal-content"></div>
|
||||
<div class="col s12 modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-green btn red">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
10
app/templates/modals/show_text_details.html.j2
Normal file
10
app/templates/modals/show_text_details.html.j2
Normal file
@ -0,0 +1,10 @@
|
||||
<!-- Modal to show all metadata of one text/corpus file. Used in conjunction with the show_meta_data.html.j2 template. -->
|
||||
<div id="modal-text-details" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4>Bibliographic data</h4>
|
||||
<p id="bibliographic-data"></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class="modal-close waves-effect waves-green red btn">Close</a>
|
||||
</div>
|
||||
</div>
|
14
app/templates/services/_breadcrumbs.html.j2
Normal file
14
app/templates/services/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,14 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a href="{{ url_for('main.index', _anchor='services') }}" target="_self">Processes & Services</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('.service', service='corpus_analysis') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.service', service='corpus_analysis') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.service', service='file_setup') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.service', service='file_setup') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.service', service='nlp') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.service', service='nlp') }}" target="_self">{{ title }}</a></li>
|
||||
{% elif request.path == url_for('.service', service='ocr') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('.service', service='ocr') }}" target="_self">{{ title }}</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
99
app/templates/services/corpus_analysis.html.j2
Normal file
99
app/templates/services/corpus_analysis.html.j2
Normal file
@ -0,0 +1,99 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "services/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="corpus-analysis"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m3 push-m9">
|
||||
<div class="center-align">
|
||||
<a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light" style="transform: scale(2);">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="corpus-analysis"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m9 pull-m3">
|
||||
<p>Nopaque lets you create and upload as many text corpora as you want. It makes use of CQP Query Language, which allows for complex search requests with the aid of metadata and NLP tags. The results can either be displayed as text or abstract visualizations.</p>
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="corpora">
|
||||
<h2>My Corpora</h2>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-corpus" class="search" type="search"></input>
|
||||
<label for="search-corpus">Search corpus</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th><span class="sort" data-sort="status">Status</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="waves-effect waves-light btn" href="{{ url_for('corpora.import_corpus') }}"><i class="material-icons right">import_export</i>Import Corpus</a>
|
||||
<a class="btn waves-effect waves-light" href="{{ url_for('corpora.add_corpus') }}">New corpus<i class="material-icons right">add</i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12" id="query-results">
|
||||
<h2>My query results</h2>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
<input id="search-query-results" class="search" type="search"></input>
|
||||
<label for="search-query-results">Search query result</label>
|
||||
</div>
|
||||
<table class="highlight ressource-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<span class="sort" data-sort="title">Title</span> and<br>
|
||||
<span class="sort" data-sort="description">Description</span>
|
||||
</th>
|
||||
<th>
|
||||
<span class="sort" data-sort="corpus">Corpus</span> and<br>
|
||||
<span class="sort" data-sort="query">Query</span>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list"></tbody>
|
||||
</table>
|
||||
<ul class="pagination"></ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a class="btn waves-effect waves-light" href="{{ url_for('corpora.add_query_result') }}">Add query result<i class="material-icons right">file_upload</i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
let corpusList = new CorpusList(document.querySelector('#corpora'));
|
||||
let queryResultList = new QueryResultList(document.querySelector('#query-results'));
|
||||
</script>
|
||||
{% endblock scripts %}
|
80
app/templates/services/file_setup.html.j2
Normal file
80
app/templates/services/file_setup.html.j2
Normal file
@ -0,0 +1,80 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "services/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="file-setup"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m3 push-m9">
|
||||
<div class="center-align">
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m9 pull-m3">
|
||||
<div class="card service-color-border border-darken" data-service="file-setup" style="border-top: 10px solid;">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel z-depth-0">
|
||||
<span class="card-title"><i class="left material-icons">layers</i>Merge process</span>
|
||||
<p>nopaque converts and merges your files in its cloud infrastructure to facilitate further processing and the application of other services. You only have to number your files in the correct order to receive a PDF file.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<h2>Submit a job</h2>
|
||||
<div class="card">
|
||||
<form class="nopaque-submit-form" data-progress-modal="progress-modal">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 l4">
|
||||
{{ wtf.render_field(form.title, data_length='32', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 l8">
|
||||
{{ wtf.render_field(form.description, data_length='255', material_icon='description') }}
|
||||
</div>
|
||||
<div class="col s12 l9">
|
||||
{{ wtf.render_field(form.files, accept='image/jpeg, image/png, image/tiff', placeholder='Choose your .jpeg, .png or .tiff files') }}
|
||||
</div>
|
||||
<div class="col s12 l3">
|
||||
{{ wtf.render_field(form.version, material_icon='apps') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="progress-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4><i class="material-icons prefix">file_upload</i> Uploading files...</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 %}
|
135
app/templates/services/nlp.html.j2
Normal file
135
app/templates/services/nlp.html.j2
Normal file
@ -0,0 +1,135 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "services/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="nlp"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m3 push-m9">
|
||||
<div class="center-align">
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="nlp"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m9 pull-m3">
|
||||
<div class="card service-color-border border-darken" data-service="nlp" style="border-top: 10px solid;">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12 m6">
|
||||
<div class="card-panel z-depth-0">
|
||||
<span class="card-title"><i class="left material-icons">layers</i>Tokenization</span>
|
||||
<p>Your text is split up into sentences and words, so called tokens, which can then be analyzed.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
<div class="card-panel z-depth-0">
|
||||
<span class="card-title"><i class="left material-icons">layers</i>Lemmatization</span>
|
||||
<p>All inflected forms of a word are grouped together so that it can be analyzed as a single item.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
<div class="card-panel z-depth-0">
|
||||
<span class="card-title"><i class="left material-icons">layers</i>Part-of-speech Tagging</span>
|
||||
<p>In accordance with its definition and context, each word is marked up as corresponding to a particular part of speech.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
<div class="card-panel z-depth-0">
|
||||
<span class="card-title"><i class="left material-icons">layers</i>Named-Entity Recognition</span>
|
||||
<p>Named entities are located and classified into specific categories like persons or locations.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<h2>Submit a job</h2>
|
||||
<div class="card">
|
||||
<form class="nopaque-submit-form" data-progress-modal="progress-modal">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 l4">
|
||||
{{ wtf.render_field(form.title, data_length='32', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 l8">
|
||||
{{ wtf.render_field(form.description, data_length='255', material_icon='description') }}
|
||||
</div>
|
||||
<div class="col s12 l5">
|
||||
{{ wtf.render_field(form.files, accept='text/plain', placeholder='Choose your .txt files') }}
|
||||
</div>
|
||||
<div class="col s12 l4">
|
||||
{{ wtf.render_field(form.language, material_icon='language') }}
|
||||
</div>
|
||||
<div class="col s12 l3">
|
||||
{{ wtf.render_field(form.version, material_icon='apps') }}
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<span class="card-title">Preprocessing</span>
|
||||
</div>
|
||||
<div class="col s9">
|
||||
<p>{{ form.check_encoding.label.text }}</p>
|
||||
<p class="light">If the input files are not created with the nopaque OCR service or you do not know if your text files are UTF-8 encoded, check this switch. We will try to automatically determine the right encoding for your texts to process them.</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
{{ form.check_encoding() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
Seperate each setting with the following
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="progress-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4><i class="material-icons prefix">file_upload</i> Uploading files...</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 %}
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
var versionField = document.querySelector('#add-nlp-job-form-version');
|
||||
versionField.addEventListener('change', (event) => {
|
||||
let url = new URL(window.location.href);
|
||||
url.search = `?version=${event.target.value}`;
|
||||
window.location.href = url.toString();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
162
app/templates/services/ocr.html.j2
Normal file
162
app/templates/services/ocr.html.j2
Normal file
@ -0,0 +1,162 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "services/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block main_attribs %} class="service-scheme" data-service="ocr"{% endblock main_attribs %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m3 push-m9">
|
||||
<div class="center-align">
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<p class="hide-on-small-only"> </p>
|
||||
<a class="btn-floating btn-large btn-scale-x2 waves-effect waves-light">
|
||||
<i class="nopaque-icons service-color darken service-icon" data-service="ocr"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m9 pull-m3">
|
||||
<div class="card service-color-border border-darken" data-service="ocr" style="border-top: 10px solid;">
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel z-depth-0">
|
||||
<span class="card-title"><i class="left material-icons">layers</i>OCR</span>
|
||||
<p>In this process, nopaque converts your image data – like photos or scans – into text data. This step enables you to proceed with the computational analysis of your documents.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12">
|
||||
<h2>Submit a job</h2>
|
||||
<div class="card">
|
||||
<form class="nopaque-submit-form" data-progress-modal="progress-modal">
|
||||
<div class="card-content">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col s12 l4">
|
||||
{{ wtf.render_field(form.title, data_length='32', material_icon='title') }}
|
||||
</div>
|
||||
<div class="col s12 l8">
|
||||
{{ wtf.render_field(form.description, data_length='255', material_icon='description') }}
|
||||
</div>
|
||||
<div class="col s12 l5">
|
||||
{{ wtf.render_field(form.files, accept='application/pdf', color=ocr_color_darken, placeholder='Choose your .pdf files') }}
|
||||
</div>
|
||||
<div class="col s12 l4">
|
||||
{{ wtf.render_field(form.language, material_icon='language') }}
|
||||
</div>
|
||||
<div class="col s12 l3">
|
||||
{{ wtf.render_field(form.version, material_icon='apps') }}
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<span class="card-title">Preprocessing</span>
|
||||
</div>
|
||||
<div class="col s9">
|
||||
<p>{{ form.binarization.label.text }}</p>
|
||||
<p class="light">Based on a brightness threshold pixels are converted into either black or white. It is useful to reduce noise in images. (<b>longer duration</b>)</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
{{ form.binarization() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s9">
|
||||
<p>Page range</p>
|
||||
<p class="light"></p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input disabled type="checkbox">
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s9">
|
||||
<p>Page rotation</p>
|
||||
<p class="light"></p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input disabled type="checkbox">
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s9">
|
||||
<p>Page split</p>
|
||||
<p class="light"></p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
<input disabled type="checkbox">
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
Seperate each setting with the following
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s12 divider"></div>
|
||||
<div class="col s12"><p> </p></div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
{{ wtf.render_field(form.submit, color=ocr_color_darken, material_icon='send') }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="progress-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4><i class="material-icons left">file_upload</i>Uploading files...</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 %}
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
var versionField = document.querySelector('#add-ocr-job-form-version');
|
||||
versionField.addEventListener('change', (event) => {
|
||||
let url = new URL(window.location.href);
|
||||
url.search = `?version=${event.target.value}`;
|
||||
window.location.href = url.toString();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
12
app/templates/settings/_breadcrumbs.html.j2
Normal file
12
app/templates/settings/_breadcrumbs.html.j2
Normal file
@ -0,0 +1,12 @@
|
||||
{% set breadcrumbs %}
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
<li class="tab"><a{%if request.path == url_for('settings.index') %} class="active"{% endif %} href="{{ url_for('settings.index') }}" target="_self">Settings</a></li>
|
||||
<li class="tab disabled"><i class="material-icons">navigate_next</i></li>
|
||||
{% if request.path == url_for('settings.change_password') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('settings.change_password') }}" target="_self">Change password</a></li>
|
||||
{% elif request.path == url_for('settings.edit_general_settings') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('settings.edit_general_settings') }}" target="_self">Edit general settings</a></li>
|
||||
{% elif request.path == url_for('settings.edit_notification_settings') %}
|
||||
<li class="tab"><a class="active" href="{{ url_for('settings.edit_notification_settings') }}" target="_self">Edit notification settings</a></li>
|
||||
{% endif %}
|
||||
{% endset %}
|
5
app/templates/settings/_menu.html.j2
Normal file
5
app/templates/settings/_menu.html.j2
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="collection">
|
||||
<a href="{{ url_for('.edit_general_settings') }}" class="collection-item{%if request.path == url_for('.edit_general_settings') %} active{% endif %}">Edit general settings</a>
|
||||
<a href="{{ url_for('.change_password') }}" class="collection-item{%if request.path == url_for('.change_password') %} active{% endif %}">Change password</a>
|
||||
<a href="{{ url_for('.edit_notification_settings') }}" class="collection-item{%if request.path == url_for('.edit_notification_settings') %} active{% endif %}">Edit notification settings</a>
|
||||
</div>
|
36
app/templates/settings/change_password.html.j2
Normal file
36
app/templates/settings/change_password.html.j2
Normal file
@ -0,0 +1,36 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "settings/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
{% include 'settings/_menu.html.j2' %}
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form enctype="multipart/form-data" method="POST">
|
||||
<div class="card-content">
|
||||
<span class="card-title">{{ title }}</span>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.password, material_icon='vpn_key') }}
|
||||
{{ wtf.render_field(form.new_password, material_icon='vpn_key') }}
|
||||
{{ wtf.render_field(form.new_password2, material_icon='vpn_key') }}
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<div class="right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
80
app/templates/settings/edit_general_settings.html.j2
Normal file
80
app/templates/settings/edit_general_settings.html.j2
Normal file
@ -0,0 +1,80 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "settings/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
{% include 'settings/_menu.html.j2' %}
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form enctype="multipart/form-data" method="POST">
|
||||
<div class="card-content">
|
||||
<span class="card-title">{{ title }}</span>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.username, data_length='64', material_icon='person') }}
|
||||
{{ wtf.render_field(form.email, data_length='254', material_icon='email') }}
|
||||
<div class="row">
|
||||
<div class="col s12"><p> </p></div>
|
||||
<div class="col s1">
|
||||
<p><i class="material-icons">brightness_3</i></p>
|
||||
</div>
|
||||
<div class="col s8">
|
||||
<p>{{ form.dark_mode.label.text }}</p>
|
||||
<p class="light">Enable dark mode to ease your eyes.</p>
|
||||
</div>
|
||||
<div class="col s3 right-align">
|
||||
<div class="switch">
|
||||
<label>
|
||||
{{ form.dark_mode() }}
|
||||
<span class="lever"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<div class="right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Delete account</span>
|
||||
<p>Deleting an account has the following effects:</p>
|
||||
<ul>
|
||||
<li>All data associated with your corpora and jobs will be permanently deleted.</li>
|
||||
<li>All settings will be permanently deleted.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-action right-align">
|
||||
<a href="#delete-account-modal" class="btn modal-trigger red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modals -->
|
||||
<div class="modal" id="delete-account-modal">
|
||||
<div class="modal-content">
|
||||
<h4>Confirm deletion</h4>
|
||||
<p>Do you really want to delete your account and all associated data? All associated corpora, jobs and 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('.delete') }}" class="btn red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
35
app/templates/settings/edit_notification_settings.html.j2
Normal file
35
app/templates/settings/edit_notification_settings.html.j2
Normal file
@ -0,0 +1,35 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% from "settings/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||
{% import "materialize/wtf.html.j2" as wtf %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<h1 id="title">{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
{% include 'settings/_menu.html.j2' %}
|
||||
</div>
|
||||
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<form enctype="multipart/form-data" method="POST">
|
||||
<div class="card-content">
|
||||
<span class="card-title">{{ title }}</span>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ wtf.render_field(form.job_status_mail_notifications, material_icon='notifications') }}
|
||||
{{ wtf.render_field(form.job_status_site_notifications, material_icon='feedback') }}
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<div class="right-align">
|
||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page_content %}
|
21
app/templates/tables/query_results.html.j2
Normal file
21
app/templates/tables/query_results.html.j2
Normal file
@ -0,0 +1,21 @@
|
||||
<!-- Table showing the query results of the current query or the imported
|
||||
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: 35%">Match</th>
|
||||
<th style="width: 10%">{# Actions #}</th>
|
||||
<th style="width: 25%">Right Context</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list" id="query-results-table">
|
||||
</tbody>
|
||||
</table>
|
||||
<ul class="pagination paginationBottom"></ul>
|
||||
</div>
|
8
app/templates/tasks/email/notification.html.j2
Normal file
8
app/templates/tasks/email/notification.html.j2
Normal file
@ -0,0 +1,8 @@
|
||||
<p>Dear <b>{{ job.creator.username }}</b>,</p>
|
||||
|
||||
<p>The status of your Job "<b>{{ job.title }}</b>" has changed!</p>
|
||||
<p>It is now <b>{{ job.status }}</b>!</p>
|
||||
|
||||
<p>You can access your Job here: <a href="{{ url_for('jobs.job', job_id=job.id) }}">{{ url_for('jobs.job', job_id=job.id) }}</a></p>
|
||||
|
||||
<p>Kind regards!<br>Your nopaque team</p>
|
9
app/templates/tasks/email/notification.txt.j2
Normal file
9
app/templates/tasks/email/notification.txt.j2
Normal file
@ -0,0 +1,9 @@
|
||||
Dear {{ job.creator.username }},
|
||||
|
||||
The status of your Job "{{ job.title }}" has changed!
|
||||
It is now {{ job.status }}!
|
||||
|
||||
You can access your Job here: {{ url_for('jobs.job', job_id=job.id) }}
|
||||
|
||||
Kind regards!
|
||||
Your nopaque team
|
Reference in New Issue
Block a user