intermediate

This commit is contained in:
Patrick Jentsch 2020-10-23 08:51:46 +02:00
parent 0ef7355ca1
commit 23441dab2e
19 changed files with 1249 additions and 1149 deletions

View File

@ -0,0 +1,12 @@
/*
* The sidenav-fixed class is used which causes the sidenav to be fixed and open
* on large screens and hides to the regular functionality on smaller screens.
* In order to prevent the sidenav to overlap the content, the content (in our
* case header, main and footer) gets an offset equal to the width of the
* sidenav.
*/
@media only screen and (min-width : 993px) {
header, main, footer {padding-left: 300px;}
.modal:not(.bottom-sheet) {left: 300px;}
.navbar-fixed > nav {width: calc(100% - 300px)}
}

View File

@ -0,0 +1,13 @@
/*
* Force the footer to always stay on the bottom of the page regardless of how
* little content is on the page.
*/
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}

View File

@ -1,19 +1,3 @@
/*
* ### Start sticky footer ###
* Force the footer to always stay on the bottom of the page regardless of how
* little content is on the page.
*/
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
/* ### End sticky footer ### */
/* add custom bold class */
.bold {
font-weight: bold;

View File

@ -4,12 +4,8 @@
*/
var nopaque = {};
// nopaque ressources
nopaque.socket = undefined;
// User data
nopaque.user = {};
nopaque.user.isAuthenticated = undefined;
nopaque.user.settings = {};
nopaque.user.settings.darkMode = undefined;
nopaque.corporaSubscribers = [];
@ -25,11 +21,7 @@ nopaque.foreignCorporaSubscribers = [];
nopaque.foreignJobsSubscribers = [];
nopaque.foreignQueryResultsSubscribers = [];
nopaque.flashedMessages = undefined;
// nopaque functions
nopaque.socket = {};
nopaque.socket.init = function() {
nopaque.socket = io({transports: ['websocket']});
// Add event handlers
nopaque.socket.on("user_data_stream_init", function(msg) {
@ -99,7 +91,6 @@ nopaque.socket.init = function() {
for (let subscriber of nopaque.foreignJobsSubscribers) {subscriber._update(jobs_patch);}
for (let subscriber of nopaque.foreignQueryResultsSubscribers) {subscriber._update(query_results_patch);}
});
}
nopaque.Forms = {};
nopaque.Forms.init = function() {
@ -173,32 +164,10 @@ nopaque.Forms.init = function() {
}
}
nopaque.Navigation = {};
nopaque.Navigation.init = function() {
/* ### Initialize sidenav-main ### */
for (let entry of document.querySelectorAll("#sidenav-main a")) {
if (entry.href === window.location.href) {
entry.parentNode.classList.add("active");
}
}
}
nopaque.flash = function() {
var classes, toast, toastActionElement;
switch (arguments.length) {
case 1:
category = "message";
message = arguments[0];
break;
case 2:
message = arguments[0];
category = arguments[1];
break;
default:
console.error("Usage: nopaque.flash(message) or nopaque.flash(message, category)")
}
nopaque.flash = function(message, category) {
let toast;
let toastActionElement;
switch (category) {
case "corpus":
@ -219,27 +188,5 @@ nopaque.flash = function() {
<i class="material-icons">close</i>
</button>`});
toastActionElement = toast.el.querySelector('.toast-action[data-action="close"]');
if (toastActionElement) {
toastActionElement.addEventListener('click', function() {
toast.dismiss();
});
toastActionElement.addEventListener('click', () => {toast.dismiss();});
}
}
document.addEventListener('DOMContentLoaded', () => {
// 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="text"]'));
M.Dropdown.init(document.querySelectorAll('#nav-notifications, #nav-account'),
{alignment: 'right', constrainWidth: false, coverTrigger: false});
nopaque.Forms.init();
nopaque.Navigation.init();
while (nopaque.flashedMessages.length) {
flashedMessage = nopaque.flashedMessages.shift();
nopaque.flash(flashedMessage[1], flashedMessage[0]);
}
});

View File

@ -0,0 +1,19 @@
{% set colors = {'primary': '#00426f',
'secondary': '#b1b3b4',
'corpus_analysis': '#aa9cc9',
'corpus_analysis_darken': '#6b3f89',
'corpus_analysis_lighten': '#ebe8f6',
'file_setup': '#d5dc95',
'file_setup_darken': '#a1b300',
'file_setup_lighten': '#f2f3e1',
'nlp': '#98acd2',
'nlp_darken': '#0064a3',
'nlp_lighten': '#e5e8f5',
'ocr': '#a9d8c8',
'ocr_darken': '#00a58b',
'ocr_lighten': '#e7f4f1'} %}
{% if main_class is not defined %}
{% set main_class = 'grey lighten-5' %}
{% endif %}

View File

@ -1,8 +1,8 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% set headline = ' ' %}
{% block page_content %}
{% block styles %}
{{ super() }}
<style>
main {
background-image: url("{{ url_for('static', filename='images/parallax_lq/04_german_text_book_paper.jpg') }}");
@ -10,15 +10,19 @@
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">
<h2>Log in</h2>
<h1>{{ 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('auth.register') }}"><i class="material-icons left">person_add</i>Register</a>
<a class="btn" href="{{ url_for('.register') }}"><i class="material-icons left">person_add</i>Register</a>
</div>
</div>
</div>
@ -28,21 +32,23 @@
<form method="POST">
<div class="card-content">
{{ login_form.hidden_tag() }}
{{ M.render_field(login_form.user, material_icon='person') }}
{{ M.render_field(login_form.password, material_icon='vpn_key') }}
{{ wtf.render_field(login_form.user, material_icon='person') }}
{{ wtf.render_field(login_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>
<a href="{{ url_for('.reset_password_request') }}">Forgot your password?</a>
</div>
<div class="col s6 right-align">
{{ M.render_field(login_form.remember_me) }}
{{ wtf.render_field(login_form.remember_me) }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(login_form.submit, material_icon='send') }}
{{ wtf.render_field(login_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,8 +1,8 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% set headline = ' ' %}
{% block page_content %}
{% block styles %}
{{ super() }}
<style>
main {
background-image: url("{{ url_for('static', filename='images/parallax_lq/02_concept_document_focus_letter.jpg') }}");
@ -10,11 +10,15 @@
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">
<h2>Register</h2>
<h1>Register</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>
@ -27,15 +31,17 @@
<form method="POST">
<div class="card-content">
{{ registration_form.hidden_tag() }}
{{ M.render_field(registration_form.username, data_length='64', material_icon='person') }}
{{ M.render_field(registration_form.password, data_length='128', material_icon='vpn_key') }}
{{ M.render_field(registration_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
{{ M.render_field(registration_form.email, class_='validate', material_icon='email', type='email') }}
{{ wtf.render_field(registration_form.username, data_length='64', material_icon='person') }}
{{ wtf.render_field(registration_form.password, data_length='128', material_icon='vpn_key') }}
{{ wtf.render_field(registration_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
{{ wtf.render_field(registration_form.email, class_='validate', material_icon='email', type='email') }}
</div>
<div class="card-action right-align">
{{ M.render_field(registration_form.submit, material_icon='send') }}
{{ wtf.render_field(registration_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,8 +1,14 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12 m4">
<h3>Lorem ipsum</h3>
<p>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>
</div>
@ -11,13 +17,15 @@
<form method="POST">
<div class="card-content">
{{ reset_password_form.hidden_tag() }}
{{ M.render_field(reset_password_form.password, data_length='128') }}
{{ M.render_field(reset_password_form.password_confirmation, data_length='128') }}
{{ wtf.render_field(reset_password_form.password, data_length='128') }}
{{ wtf.render_field(reset_password_form.password_confirmation, data_length='128') }}
</div>
<div class="card-action right-align">
{{ M.render_field(reset_password_form.submit, material_icon='send') }}
{{ wtf.render_field(reset_password_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,6 +1,13 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ 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>
@ -10,12 +17,14 @@
<form method="POST">
<div class="card-content">
{{ reset_password_request_form.hidden_tag() }}
{{ M.render_field(reset_password_request_form.email, class_='validate', material_icon='email', type='email') }}
{{ wtf.render_field(reset_password_request_form.email, class_='validate', material_icon='email', type='email') }}
</div>
<div class="card-action right-align">
{{ M.render_field(reset_password_request_form.submit, material_icon='send') }}
{{ wtf.render_field(reset_password_request_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,20 +1,25 @@
{% extends "nopaque.html.j2" %}
{% block title %}Opaque - Confirm your account{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>
Hello, {{ current_user.username }}!
</h1>
<h3>You have not confirmed your account yet.</h3>
<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?
<a href="{{ url_for('auth.resend_confirmation') }}">Click here</a>
</p>
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ 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? <a href="{{ url_for('.resend_confirmation') }}">Click here</a></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>
</div>
{% endblock %}

View File

@ -1,6 +1,11 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="card">
@ -255,5 +260,6 @@
</li>
</ul>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,6 +1,12 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ 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>
@ -161,11 +167,16 @@
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
{{ super() }}
<script type="module">
import {RessourceList} from '../../static/js/nopaque.lists.js';
let corpusList = new RessourceList("corpora", nopaque.corporaSubscribers, "Corpus");
let jobList = new RessourceList("jobs", nopaque.jobsSubscribers, "Job");
let queryResultList = new RessourceList("query-results", nopaque.queryResultsSubscribers, "QueryResult");
</script>
{% endblock %}
{% endblock scripts %}

View File

@ -1,6 +1,5 @@
{% extends "nopaque.html.j2" %}
{% set parallax = True %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="section white">
@ -157,19 +156,19 @@
<div class="card-content">
<span class="card-title">Log in</span>
{{ login_form.hidden_tag() }}
{{ M.render_field(login_form.user, material_icon='person') }}
{{ M.render_field(login_form.password, material_icon='vpn_key') }}
{{ wtf.render_field(login_form.user, material_icon='person') }}
{{ wtf.render_field(login_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">
{{ M.render_field(login_form.remember_me) }}
{{ wtf.render_field(login_form.remember_me) }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(login_form.submit, material_icon='send') }}
{{ wtf.render_field(login_form.submit, material_icon='send') }}
</div>
</form>
</div>

View File

@ -1,6 +1,11 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="card" id="beta-launch">
<div class="card-content">
@ -12,4 +17,6 @@
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,6 +1,12 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ 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>
@ -143,5 +149,6 @@
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,6 +1,11 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ 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>
@ -101,5 +106,6 @@
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,35 @@
{% 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_design_icons.min.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 %}
{% block navbar %}
{% endblock navbar %}
{% block sidenav %}
{% endblock sidenav %}
{% block content %}
{% endblock content %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
{% endblock scripts %}
{% endblock body %}
</body>
{% endblock html %}
</html>
{% endblock doc %}

View 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 %}

View File

@ -1,212 +1,137 @@
{% import "utils/macros.html.j2" as Macros %}
{% import "utils/materialize.html.j2" as M %}
{% extends "materialize/base.html.j2" %}
{% from '_variables.html.j2' import colors %}
{% block html_attribs %} lang="en"{% endblock html_attribs %}
{% if title is not defined %}
{% set title = None %}
{% endif %}
{% block head %}
{{ super() }}
<link href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}" rel="icon">
{% endblock head %}
{% if headline is not defined %}
{% set headline = title %}
{% endif %}
{% if parallax is not defined %}
{% set parallax = False %}
{% endif %}
{% if main_class is not defined %}
{% set main_class = 'grey lighten-5' %}
{% endif %}
{% set primary_color = '#00426f' %}
{% set secondary_color = '#b1b3b4' %}
{% set corpus_analysis_color = '#aa9cc9' %}
{% set corpus_analysis_color_darken = '#6b3f89' %}
{% set corpus_analysis_color_lighten = '#ebe8f6' %}
{% set file_setup_color = '#d5dc95' %}
{% set file_setup_color_darken = '#a1b300' %}
{% set file_setup_color_lighten = '#f2f3e1' %}
{% set nlp_color = '#98acd2' %}
{% set nlp_color_darken = '#0064a3' %}
{% set nlp_color_lighten = '#e5e8f5' %}
{% set ocr_color = '#a9d8c8' %}
{% set ocr_color_darken = '#00a58b' %}
{% set ocr_color_lighten = '#e7f4f1' %}
{%- macro insert_content() -%}
{% block page_content %}{% endblock %}
{%- endmacro -%}
<!DOCTYPE html>
<html lang="en">
<head>
{% block metas %}
<meta charset="UTF-8">
<meta name="theme-color" content="#ee6e73">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
nopaque
{% if request.path != url_for('main.index') %} {{ title }}{% endif %}
</title>
<link rel="icon" href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}">
<!--Import Google Icon Font-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/material_design_icons.min.css') }}">
<!--Import materialize.css-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/materialize.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/nopaque.css') }}">
<style>
.primary-color {background-color: {{ primary_color }} !important;}
.primary-color-text {color: {{ primary_color }} !important;}
.secondary-color {background-color: {{ secondary_color }} !important;}
.secondary-color-text {color: {{ secondary_color }} !important;}
{{ super() }}
{% endblock metas %}
.corpus-analysis-color {background-color: {{ corpus_analysis_color }} !important;}
.corpus-analysis-color-text {color: {{ corpus_analysis_color }} !important;}
.corpus-analysis-color.darken {background-color: {{ corpus_analysis_color_darken }} !important;}
.corpus-analysis-color-text.text-darken {color: {{ corpus_analysis_color_darken }} !important;}
.corpus-analysis-color.lighten {background-color: {{ corpus_analysis_color_lighten }} !important;}
.corpus-analysis-color-text.text-lighten {color: {{ corpus_analysis_color_lighten }} !important;}
{% block title %}{% if request.path != url_for('main.index') and title is defined %}{{title}} | {% endif %}nopaque{% endblock title %}
.file-setup-color {background-color: {{ file_setup_color }} !important;}
.file-setup-color-text {color: {{ file_setup_color }} !important;}
.file-setup-color.darken {background-color: {{ file_setup_color_darken }} !important;}
.file-setup-color-text.text-darken {color: {{ file_setup_color_darken }} !important;}
.file-setup-color.lighten {background-color: {{ file_setup_color_lighten }} !important;}
.file-setup-color-text.text-lighten {color: {{ file_setup_color_lighten }} !important;}
.ocr-color {background-color: {{ ocr_color }} !important;}
.ocr-color-text {color: {{ ocr_color }} !important;}
.ocr-color.darken {background-color: {{ ocr_color_darken }} !important;}
.ocr-color-text.text-darken {color: {{ ocr_color_darken }} !important;}
.ocr-color.lighten {background-color: {{ ocr_color_lighten }} !important;}
.ocr-color-text.text-lighten {color: {{ ocr_color_lighten }} !important;}
.nlp-color {background-color: {{ nlp_color }} !important;}
.nlp-color-text {color: {{ nlp_color }} !important;}
.nlp-color.darken {background-color: {{ nlp_color_darken }} !important;}
.nlp-color-text.text-darken {color: {{ nlp_color_darken }} !important;}
.nlp-color.lighten {background-color: {{ nlp_color_lighten }} !important;}
.nlp-color-text.text-lighten {color: {{ nlp_color_lighten }} !important;}
.pagination li.active {background-color: {{ primary_color }};}
.table-of-contents a.active {border-color: {{ primary_color }};}
.tabs .tab a {color: inherit; /* Custom Text Color */}
.tabs .tab a:hover {color: {{ primary_color }}; /* Custom Color On Hover */}
.tabs .tab a.active, .tabs .tab a:focus.active {
color: {{ primary_color }}; /* Custom Text Color While Active */
background-color: {{ primary_color }}28; /* Custom Background Color While Active */
}
.tabs .indicator {background-color: {{ primary_color }}; /* Custom Color Of Indicator */}
{% block styles %}
{{ super() }}
{% if current_user.is_authenticated %}
/*
* ### Start sidenav-fixed offset ###
* The sidenav-fixed class is used which causes the sidenav to be fixed and open
* on large screens and hides to the regular functionality on smaller screens.
* In order to prevent the sidenav to overlap the content, the content (in our
* case header, main and footer) gets an offset equal to the width of the
* sidenav.
*/
@media only screen and (min-width : 993px) {
header, main, footer {padding-left: 300px;}
.modal:not(.bottom-sheet) {left: 300px;}
.navbar-fixed > nav {width: calc(100% - 300px)}
}
/* ### End sidenav-fixed offset ### */
<link href="{{ url_for('static', filename='css/materialize.fix.sidenav-fixed.css') }}" media="screen,projection" rel="stylesheet">
{% endif %}
<link href="{{ url_for('static', filename='css/materialize.fix.sticky-footer.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-text {color: {{ colors.primary }} !important;}
.secondary-color {background-color: {{ colors.secondary }} !important;}
.secondary-color-text {color: {{ colors.secondary }} !important;}
.corpus-analysis-color {background-color: {{ colors.corpus_analysis }} !important;}
.corpus-analysis-color-text {color: {{ colors.corpus_analysis }} !important;}
.corpus-analysis-color.darken {background-color: {{ colors.corpus_analysis_darken }} !important;}
.corpus-analysis-color-text.text-darken {color: {{ colors.corpus_analysis_darken }} !important;}
.corpus-analysis-color.lighten {background-color: {{ colors.corpus_analysis_lighten }} !important;}
.corpus-analysis-color-text.text-lighten {color: {{ colors.corpus_analysis_lighten }} !important;}
.file-setup-color {background-color: {{ colors.file_setup }} !important;}
.file-setup-color-text {color: {{ colors.file_setup }} !important;}
.file-setup-color.darken {background-color: {{ colors.file_setup_darken }} !important;}
.file-setup-color-text.text-darken {color: {{ colors.file_setup_darken }} !important;}
.file-setup-color.lighten {background-color: {{ colors.file_setup_lighten }} !important;}
.file-setup-color-text.text-lighten {color: {{ colors.file_setup_lighten }} !important;}
.ocr-color {background-color: {{ colors.ocr }} !important;}
.ocr-color-text {color: {{ colors.ocr }} !important;}
.ocr-color.darken {background-color: {{ colors.ocr_darken }} !important;}
.ocr-color-text.text-darken {color: {{ colors.ocr_darken }} !important;}
.ocr-color.lighten {background-color: {{ colors.ocr_lighten }} !important;}
.ocr-color-text.text-lighten {color: {{ colors.ocr_lighten }} !important;}
.nlp-color {background-color: {{ colors.nlp }} !important;}
.nlp-color-text {color: {{ colors.nlp }} !important;}
.nlp-color.darken {background-color: {{ colors.nlp_darken }} !important;}
.nlp-color-text.text-darken {color: {{ colors.nlp_darken }} !important;}
.nlp-color.lighten {background-color: {{ colors.nlp_lighten }} !important;}
.nlp-color-text.text-lighten {color: {{ colors.nlp_lighten }} !important;}
.pagination li.active {background-color: {{ colors.primary }};}
.table-of-contents a.active {border-color: {{ colors.primary }};}
.tabs .tab a {color: inherit; /* Custom Text Color */}
.tabs .tab a:hover {color: {{ colors.primary }}; /* Custom Color On Hover */}
.tabs .tab a.active, .tabs .tab a:focus.active {
color: {{ colors.primary }}; /* Custom Text Color While Active */
background-color: {{ colors.primary }}28; /* Custom Background Color While Active */
}
.tabs .indicator {background-color: {{ colors.primary }}; /* Custom Color Of Indicator */}
</style>
</head>
<body>
{% endblock styles %}
{% block navbar %}
<header>
<div class="navbar-fixed">
<nav class="nav-extended primary-color white-text">
<div class="nav-wrapper">
<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 hide-on-med-and-down" style="height: 100%; overflow: hidden;"><img src="{{ url_for('static', filename='images/nopaque_-_logo_name_slogan.svg') }}" style="height: 128px; margin-top: -32px;"></a>
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-large-only" style="height: 100%; overflow: hidden;"><img src="{{ url_for('static', filename='images/nopaque_-_logo.svg') }}" style="height: 128px; margin-top: -32px;"></a>
{% if current_user.is_authenticated %}
<a href="#" data-target="sidenav-main" class="sidenav-trigger"><i class="material-icons">menu</i></a>
{% endif %}
<ul class="right">
{% if current_user.is_authenticated %}
<li>
<a id="nav-notifications" class="dropdown-trigger no-autoinit" href="{{ url_for('main.news') }}" data-target="nav-notifications-dropdown">
<span class="hide-on-small-only">News</span>
<i class="material-icons right">notifications</i>
</a>
</li>
{% endif %}
<li>
<a id="nav-account" class="dropdown-trigger no-autoinit" href="#!" data-target="nav-account-dropdown">
{% if current_user.is_authenticated %}
<span class="hide-on-small-only">{{ current_user.username }}</span><i class="material-icons right">account_circle</i>
<ul class="right hide-on-med-and-down">
<li{% if request.path == url_for('main.news') %} class="active"{% endif %}><a href="{{ url_for('main.news') }}"><i class="material-icons left">notifications</i>News</a></li>
{% if current_user.is_anonymous %}
<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>
{% else %}
<i class="material-icons">account_circle</i>
<li{% if request.path == url_for('main.dashboard', _anchor='corpora') %} class="active"{% endif %}><a href="{{ url_for('main.dashboard', _anchor='corpora') }}"><i class="material-icons left">book</i>My Corpora</a></li>
<li{% if request.path == url_for('main.dashboard', _anchor='jobs') %} class="active"{% endif %}><a href="{{ url_for('main.dashboard', _anchor='jobs') }}"><i class="material-icons left">work</i>My Jobs</a></li>
<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>
{% endif %}
</a>
</li>
</ul>
</div>
<div class="nav-content">
<noscript>
<div class="card z-depth-0" style="background-color: inherit;">
<div class="card-content">
<span class="card-title">JavaScript is disabled</span>
<p>
You have JavaScript disabled. Nopaque uses javascript and
sockets to send data in realtime to you. For example showing
you the status of your jobs and your corpora.
Please activate JavaScript to make full use of nopaque.</p>
<p>Some services are still useable without Javascript.</p>
</div>
<div class="card-action">
<a href="#">What services can I still use?</a>
<a href="#">What services and functions are not available?</a>
</div>
</div>
</noscript>
<div class="nav-content secondary-color">
{% block nav_content %}{% endblock nav_content %}
</div>
</nav>
</div>
<!-- Dropdown menus for the navbar -->
<div id="nav-notifications-dropdown" class="dropdown-content">
<li>
<a href="{{ url_for('main.news', _anchor='beta-launch') }}"><i class="material-icons">error_outline</i>nopaque's beta launch</a>
</li>
</div>
<ul id="nav-account-dropdown" class="dropdown-content">
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li>
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li>
{% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="material-icons">login</i>Log in</a></li>
<li><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li>
{% endif %}
<ul class="dropdown-content" id="nav-more-dropdown">
<li><a href="{{ url_for('profile.settings') }}"><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>
</ul>
{% endif %}
</header>
{% endblock navbar %}
<ul id="sidenav-main" class="sidenav sidenav-fixed{% if not current_user.is_authenticated %} hide{% endif %}">
<li><a href="{{ url_for('main.index') }}"><i class="material-icons">opacity</i>nopaque</a></li>
{% block sidenav %}
<ul class="sidenav sidenav-fixed{% if not current_user.is_authenticated %} hide{% endif %}" id="sidenav">
{% if current_user.is_authenticated %}
<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="#"><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="material-icons">book</i>My Corpora</a></li>
<li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="material-icons">work</i>My Jobs</a></li>
<li><div class="divider"></div></li>
<li><a class="subheader">Processes & Services</a></li>
<li style="background-color: {{ file_setup_color }}; border-left: 10px solid {{ file_setup_color_darken }};"><a href="{{ url_for('services.service', service='file-setup') }}"><i class="material-icons">burst_mode</i>File setup</a></li>
<li style="background-color: {{ ocr_color }}; border-left: 10px solid {{ ocr_color_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li>
<li style="background-color: {{ nlp_color }}; border-left: 10px solid {{ nlp_color_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li>
<li style="background-color: {{ corpus_analysis_color }}; border-left: 10px solid {{ corpus_analysis_color_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="material-icons">search</i>Corpus analysis</a></li>
<li><div class="divider"></div></li>
<li><a class="subheader">Account</a></li>
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li>
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li>
<li style="background-color: {{ colors.file_setup }}; border-left: 10px solid {{ colors.file_setup_darken }};"><a href="{{ url_for('services.service', service='file-setup') }}"><i class="material-icons">burst_mode</i>File setup</a></li>
<li style="background-color: {{ colors.ocr }}; border-left: 10px solid {{ colors.ocr_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li>
<li style="background-color: {{ colors.nlp }}; border-left: 10px solid {{ colors.nlp_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li>
<li style="background-color: {{ colors.corpus_analysis }}; border-left: 10px solid {{ colors.corpus_analysis_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="material-icons">search</i>Corpus analysis</a></li>
<li class="hide-on-large-only"><div class="divider"></div></li>
<li class="hide-on-large-only"><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.logout') }}">Log out</a></li>
{% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li>
<li><a href="{{ url_for('auth.register') }}"><i class="material-icons">person_add</i>Register</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.login') }}"><i class="material-icons">login</i>Log in</a></li>
{% endif %}
{% if current_user.is_administrator() %}
<li><div class="divider"></div></li>
@ -214,31 +139,14 @@
<li><a href="{{ url_for('admin.index') }}"><i class="material-icons">build</i>Administration tools</a></li>
{% endif %}
</ul>
</header>
{% endblock sidenav %}
{% if parallax %}
{% block content %}
<main>
{{ insert_content() }}
</main>
{% else %}
<main class="{{ main_class }}">
{% if not full_width %}
<div class="container">
{% endif %}
<div class="row">
<div class="col s12" id="headline">
<h2>{{ headline }}</h2>
</div>
{{ insert_content() }}
</div>
{% if not full_width %}
</div>
{% endif %}
</div>
{% endif %}
{% block page_content %}{% endblock page_content %}
</main>
<footer class="page-footer secondary-color white-text">
<footer class="page-footer secondary-color">
<div class="container">
<div class="row">
<div class="col s6 m3">
@ -262,7 +170,7 @@
</div>
</div>
</div>
<div class="footer-copyright primary-color white-text">
<div class="footer-copyright primary-color">
<div class="container">
<div class="row" style="margin-bottom: 0;">
<div class="col s12 m3">
@ -270,31 +178,42 @@
</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>
<a class="btn-small pink waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?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.CONTACT_EMAIL_ADRESS }}?subject={{ config.NOPAQUE_MAIL_SUBJECT_PREFIX }} Feedback"><i class="left material-icons">feedback</i>Feedback</a>
<a class="btn-small orange waves-effect waves-light" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/opaque"><i class="left material-icons">code</i>GitLab</a>
{% if config.CONTACT_EMAIL_ADRESS %}
<a class="btn-small pink waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?subject=[nopaque] Contact"><i class="left material-icons">rate_review</i>Contact</a>
<a class="btn-small green waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?subject=[nopaque] 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>
</footer>
{% endblock content %}
{% block scripts %}
{{ super() }}
<script src="{{ url_for('static', filename='js/darkreader.js') }}"></script>
<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/materialize.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/socket.io.slim.js') }}"></script>
<script src="{{ url_for('static', filename='js/nopaque.js') }}"></script>
<script>
{% if current_user.is_authenticated %}
{% if current_user.setting_dark_mode %}
DarkReader.enable({brightness: 150, contrast: 100, sepia: 0});
{% endif %}
document.addEventListener('DOMContentLoaded', () => {
nopaque.socket.init();
// 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.Forms.init();
{% if current_user.is_authenticated %}
nopaque.socket.emit('user_data_stream_init');
});
{% endif %}
nopaque.flashedMessages = {{ get_flashed_messages(with_categories=True)|tojson }};
for (let flashedMessage of {{ get_flashed_messages(with_categories=True)|tojson }}) {
nopaque.flash(flashedMessage[1], flashedMessage[0]);
}
</script>
</body>
</html>
{% endblock scripts %}