mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-12-26 11:24:18 +00:00
Compare commits
3 Commits
6aacac2419
...
fc8b11fa66
Author | SHA1 | Date | |
---|---|---|---|
|
fc8b11fa66 | ||
|
a8ab1bee71 | ||
|
ee7f64f5be |
@ -104,15 +104,6 @@ def create_app(config: Config = Config) -> Flask:
|
|||||||
from .blueprints.contributions import bp as contributions_blueprint
|
from .blueprints.contributions import bp as contributions_blueprint
|
||||||
app.register_blueprint(contributions_blueprint, url_prefix='/contributions')
|
app.register_blueprint(contributions_blueprint, url_prefix='/contributions')
|
||||||
|
|
||||||
from .blueprints.spacy_nlp_pipeline_models import bp as spacy_nlp_pipeline_models_blueprint
|
|
||||||
app.register_blueprint(spacy_nlp_pipeline_models_blueprint, url_prefix='/spacy-nlp-pipeline-models')
|
|
||||||
|
|
||||||
from .blueprints.tesseract_ocr_pipeline_models import bp as tesseract_ocr_pipeline_models_blueprint
|
|
||||||
app.register_blueprint(tesseract_ocr_pipeline_models_blueprint, url_prefix='/tesseract-ocr-pipeline-models')
|
|
||||||
|
|
||||||
from.blueprints.transkribus_htr_pipeline_models import bp as transkribus_htr_pipeline_models_blueprint
|
|
||||||
app.register_blueprint(transkribus_htr_pipeline_models_blueprint, url_prefix='/transkribus-htr-pipeline-models')
|
|
||||||
|
|
||||||
from .blueprints.corpora import bp as corpora_blueprint
|
from .blueprints.corpora import bp as corpora_blueprint
|
||||||
app.register_blueprint(corpora_blueprint, cli_group='corpus', url_prefix='/corpora')
|
app.register_blueprint(corpora_blueprint, cli_group='corpus', url_prefix='/corpora')
|
||||||
|
|
||||||
|
@ -1,5 +1,29 @@
|
|||||||
from flask import Blueprint
|
from flask import Blueprint, redirect, request, url_for
|
||||||
|
from flask_login import current_user
|
||||||
|
from app import db
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint('auth', __name__)
|
bp = Blueprint('auth', __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.before_app_request
|
||||||
|
def before_request():
|
||||||
|
if not current_user.is_authenticated:
|
||||||
|
return
|
||||||
|
|
||||||
|
current_user.ping()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
if (
|
||||||
|
not current_user.confirmed
|
||||||
|
and request.endpoint
|
||||||
|
and request.blueprint != 'auth'
|
||||||
|
and request.endpoint != 'static'
|
||||||
|
):
|
||||||
|
return redirect(url_for('auth.unconfirmed'))
|
||||||
|
|
||||||
|
if not current_user.terms_of_use_accepted:
|
||||||
|
return redirect(url_for('main.terms_of_use'))
|
||||||
|
|
||||||
|
|
||||||
from . import routes
|
from . import routes
|
||||||
|
@ -12,26 +12,6 @@ from .forms import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.before_app_request
|
|
||||||
def before_request():
|
|
||||||
"""
|
|
||||||
Checks if a user is unconfirmed when visiting specific sites. Redirects to
|
|
||||||
unconfirmed view if user is unconfirmed.
|
|
||||||
"""
|
|
||||||
if not current_user.is_authenticated:
|
|
||||||
return
|
|
||||||
|
|
||||||
current_user.ping()
|
|
||||||
db.session.commit()
|
|
||||||
if (not current_user.confirmed
|
|
||||||
and request.endpoint
|
|
||||||
and request.blueprint != 'auth'
|
|
||||||
and request.endpoint != 'static'):
|
|
||||||
return redirect(url_for('auth.unconfirmed'))
|
|
||||||
if not current_user.terms_of_use_accepted:
|
|
||||||
return redirect(url_for('main.terms_of_use'))
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/register', methods=['GET', 'POST'])
|
@bp.route('/register', methods=['GET', 'POST'])
|
||||||
def register():
|
def register():
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
|
@ -16,3 +16,10 @@ def before_request():
|
|||||||
|
|
||||||
|
|
||||||
from . import routes
|
from . import routes
|
||||||
|
|
||||||
|
|
||||||
|
from .spacy_nlp_pipeline_models import bp as spacy_nlp_pipeline_models_bp
|
||||||
|
bp.register_blueprint(spacy_nlp_pipeline_models_bp, url_prefix='/spacy-nlp-pipeline-models')
|
||||||
|
|
||||||
|
from .tesseract_ocr_pipeline_models import bp as tesseract_ocr_pipeline_models_bp
|
||||||
|
bp.register_blueprint(tesseract_ocr_pipeline_models_bp, url_prefix='/tesseract-ocr-pipeline-models')
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from flask import redirect, url_for
|
from flask import render_template
|
||||||
from . import bp
|
from . import bp
|
||||||
|
|
||||||
|
|
||||||
@bp.route('')
|
@bp.route('')
|
||||||
def index():
|
def index():
|
||||||
return redirect(url_for('main.dashboard', _anchor='contributions'))
|
return render_template('contributions/index.html.j2', title='Contributions')
|
||||||
|
@ -12,10 +12,7 @@ from .forms import (
|
|||||||
@bp.route('/')
|
@bp.route('/')
|
||||||
@login_required
|
@login_required
|
||||||
def index():
|
def index():
|
||||||
return render_template(
|
return redirect(url_for('contributions.index', _anchor='spacy-nlp-pipeline-models'))
|
||||||
'spacy_nlp_pipeline_models/index.html.j2',
|
|
||||||
title='SpaCy NLP Pipeline Models'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/create', methods=['GET', 'POST'])
|
@bp.route('/create', methods=['GET', 'POST'])
|
||||||
@ -46,7 +43,7 @@ def create():
|
|||||||
flash(f'SpaCy NLP Pipeline model "{snpm.title}" created')
|
flash(f'SpaCy NLP Pipeline model "{snpm.title}" created')
|
||||||
return {}, 201, {'Location': url_for('.index')}
|
return {}, 201, {'Location': url_for('.index')}
|
||||||
return render_template(
|
return render_template(
|
||||||
'spacy_nlp_pipeline_models/create.html.j2',
|
'contributions/spacy_nlp_pipeline_models/create.html.j2',
|
||||||
title='Create SpaCy NLP Pipeline Model',
|
title='Create SpaCy NLP Pipeline Model',
|
||||||
form=form
|
form=form
|
||||||
)
|
)
|
||||||
@ -54,7 +51,7 @@ def create():
|
|||||||
|
|
||||||
@bp.route('/<hashid:spacy_nlp_pipeline_model_id>', methods=['GET', 'POST'])
|
@bp.route('/<hashid:spacy_nlp_pipeline_model_id>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
|
def entity(spacy_nlp_pipeline_model_id):
|
||||||
snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
|
snpm = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
|
||||||
if not (snpm.user == current_user or current_user.is_administrator):
|
if not (snpm.user == current_user or current_user.is_administrator):
|
||||||
abort(403)
|
abort(403)
|
||||||
@ -66,7 +63,7 @@ def spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(url_for('.index'))
|
return redirect(url_for('.index'))
|
||||||
return render_template(
|
return render_template(
|
||||||
'spacy_nlp_pipeline_models/spacy_nlp_pipeline_model.html.j2',
|
'contributions/spacy_nlp_pipeline_models/entity.html.j2',
|
||||||
title=f'{snpm.title} {snpm.version}',
|
title=f'{snpm.title} {snpm.version}',
|
||||||
form=form,
|
form=form,
|
||||||
spacy_nlp_pipeline_model=snpm
|
spacy_nlp_pipeline_model=snpm
|
@ -11,10 +11,7 @@ from .forms import (
|
|||||||
|
|
||||||
@bp.route('/')
|
@bp.route('/')
|
||||||
def index():
|
def index():
|
||||||
return render_template(
|
return redirect(url_for('contributions.index', _anchor='tesseract-ocr-pipeline-models'))
|
||||||
'tesseract_ocr_pipeline_models/index.html.j2',
|
|
||||||
title='Tesseract OCR Pipeline Models'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/create', methods=['GET', 'POST'])
|
@bp.route('/create', methods=['GET', 'POST'])
|
||||||
@ -43,14 +40,14 @@ def create():
|
|||||||
flash(f'Tesseract OCR Pipeline model "{topm.title}" created')
|
flash(f'Tesseract OCR Pipeline model "{topm.title}" created')
|
||||||
return {}, 201, {'Location': url_for('.index')}
|
return {}, 201, {'Location': url_for('.index')}
|
||||||
return render_template(
|
return render_template(
|
||||||
'tesseract_ocr_pipeline_models/create.html.j2',
|
'contributions/tesseract_ocr_pipeline_models/create.html.j2',
|
||||||
title='Create Tesseract OCR Pipeline Model',
|
title='Create Tesseract OCR Pipeline Model',
|
||||||
form=form
|
form=form
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/<hashid:tesseract_ocr_pipeline_model_id>', methods=['GET', 'POST'])
|
@bp.route('/<hashid:tesseract_ocr_pipeline_model_id>', methods=['GET', 'POST'])
|
||||||
def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
|
def entity(tesseract_ocr_pipeline_model_id):
|
||||||
topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
|
topm = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
|
||||||
if not (topm.user == current_user or current_user.is_administrator):
|
if not (topm.user == current_user or current_user.is_administrator):
|
||||||
abort(403)
|
abort(403)
|
||||||
@ -62,7 +59,7 @@ def tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(url_for('.index'))
|
return redirect(url_for('.index'))
|
||||||
return render_template(
|
return render_template(
|
||||||
'tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_model.html.j2',
|
'contributions/tesseract_ocr_pipeline_models/entity.html.j2',
|
||||||
title=f'{topm.title} {topm.version}',
|
title=f'{topm.title} {topm.version}',
|
||||||
form=form,
|
form=form,
|
||||||
tesseract_ocr_pipeline_model=topm
|
tesseract_ocr_pipeline_model=topm
|
@ -72,14 +72,14 @@ def terms_of_use():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/social-area')
|
@bp.route('/social')
|
||||||
@login_required
|
@login_required
|
||||||
def social_area():
|
def social():
|
||||||
corpora = Corpus.query.filter(Corpus.is_public == True, Corpus.user != current_user).all()
|
corpora = Corpus.query.filter(Corpus.is_public == True, Corpus.user != current_user).all()
|
||||||
users = User.query.filter(User.is_public == True, User.id != current_user.id).all()
|
users = User.query.filter(User.is_public == True, User.id != current_user.id).all()
|
||||||
return render_template(
|
return render_template(
|
||||||
'main/social_area.html.j2',
|
'main/social.html.j2',
|
||||||
title='Social Area',
|
title='Social',
|
||||||
corpora=corpora,
|
corpora=corpora,
|
||||||
users=users
|
users=users
|
||||||
)
|
)
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
from flask import Blueprint
|
|
||||||
from flask_login import login_required
|
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint('transkribus_htr_pipeline_models', __name__)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.before_request
|
|
||||||
@login_required
|
|
||||||
def before_request():
|
|
||||||
'''
|
|
||||||
Ensures that the routes in this package can only be visited by users that
|
|
||||||
are logged in.
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
from . import routes
|
|
@ -1,7 +0,0 @@
|
|||||||
from flask import abort
|
|
||||||
from . import bp
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/transkribus_htr_pipeline_models')
|
|
||||||
def index():
|
|
||||||
return abort(503)
|
|
@ -41,7 +41,7 @@ class SpaCyNLPPipelineModel(FileMixin, HashidMixin, db.Model):
|
|||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
return url_for(
|
return url_for(
|
||||||
'contributions.spacy_nlp_pipeline_model',
|
'contributions.spacy_nlp_pipeline_models.entity',
|
||||||
spacy_nlp_pipeline_model_id=self.id
|
spacy_nlp_pipeline_model_id=self.id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model):
|
|||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
return url_for(
|
return url_for(
|
||||||
'contributions.tesseract_ocr_pipeline_model',
|
'contributions.tesseract_ocr_pipeline_models.entity',
|
||||||
tesseract_ocr_pipeline_model_id=self.id
|
tesseract_ocr_pipeline_model_id=self.id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -7,26 +7,15 @@
|
|||||||
*
|
*
|
||||||
* Read more: https://materializecss.com/sidenav.html#variations
|
* Read more: https://materializecss.com/sidenav.html#variations
|
||||||
*/
|
*/
|
||||||
|
@media only screen and (min-width: 993px) {
|
||||||
|
body[data-sidenav-fixed="true" i] header,
|
||||||
body[data-sidenav-fixed="true" i] main,
|
body[data-sidenav-fixed="true" i] main,
|
||||||
body[data-sidenav-fixed="true" i] footer {
|
body[data-sidenav-fixed="true" i] footer {
|
||||||
padding-left: 300px;
|
padding-left: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 992px) {
|
|
||||||
body[data-sidenav-fixed="true" i] main,
|
|
||||||
body[data-sidenav-fixed="true" i] footer {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body[data-sidenav-fixed="true" i] .navbar-fixed > nav {
|
body[data-sidenav-fixed="true" i] .navbar-fixed > nav {
|
||||||
width: 100%;
|
width: calc(100% - 300px);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 993px) {
|
|
||||||
body[data-sidenav-fixed="true" i] .sidenav-fixed {
|
|
||||||
margin-top: 64px;
|
|
||||||
z-index: 996;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* #endregion sidenav-fixed */
|
/* #endregion sidenav-fixed */
|
||||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
@ -163,6 +163,15 @@ nopaque.App = class App {
|
|||||||
// AutoInit method (maybe they forgot it?). Anyway... We do it here. :)
|
// AutoInit method (maybe they forgot it?). Anyway... We do it here. :)
|
||||||
M.CharacterCounter.init(document.querySelectorAll('input[data-length]:not(.no-autoinit), textarea[data-length]:not(.no-autoinit)'));
|
M.CharacterCounter.init(document.querySelectorAll('input[data-length]:not(.no-autoinit), textarea[data-length]:not(.no-autoinit)'));
|
||||||
|
|
||||||
|
// Header navigation processes and services Dropdown.
|
||||||
|
M.Dropdown.init(
|
||||||
|
document.querySelector('#nav-processes-and-services-dropdown-trigger'),
|
||||||
|
{
|
||||||
|
constrainWidth: false,
|
||||||
|
coverTrigger: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Header navigation account Dropdown.
|
// Header navigation account Dropdown.
|
||||||
M.Dropdown.init(
|
M.Dropdown.init(
|
||||||
document.querySelector('#nav-account-dropdown-trigger'),
|
document.querySelector('#nav-account-dropdown-trigger'),
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
<div id="data-processing-and-analysis-modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="card-panel primary-color white-text">
|
||||||
|
<h4 class="m-3"><i class="material-icons left" style="font-size: inherit; line-height: inherit;">miscellaneous_services</i>Data Processing & Analysis</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6 l3 center-align hoverable" style="position: relative;">
|
||||||
|
<a href="{{ url_for('services.file_setup_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
|
||||||
|
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="file-setup-pipeline"></i>
|
||||||
|
<br>
|
||||||
|
<b class="service-color-text text-darken" data-service="file-setup-pipeline">File Setup</b>
|
||||||
|
<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 center-align hoverable" style="position: relative;">
|
||||||
|
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
|
||||||
|
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="tesseract-ocr-pipeline"></i>
|
||||||
|
<br>
|
||||||
|
<b class="service-color-text text-darken" data-service="tesseract-ocr-pipeline">Optical Character Recognition</b>
|
||||||
|
<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>
|
||||||
|
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
|
||||||
|
<div class="col s12 m6 l3 center-align center-align hoverable" style="position: relative;">
|
||||||
|
<a href="{{ url_for('services.transkribus_htr_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
|
||||||
|
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="transkribus-htr-pipeline"></i>
|
||||||
|
<br>
|
||||||
|
<b class="service-color-text text-darken" data-service="transkribus-htr-pipeline">Transkribus HTR Pipeline</b>
|
||||||
|
<p class="light">nopaque converts your image data – like photos or scans – into text data through HTR making it machine readable. This step enables you to proceed with further computational analysis of your documents.</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="col s12 m6 l3 center-align center-align hoverable" style="position: relative;">
|
||||||
|
<a href="{{ url_for('services.spacy_nlp_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
|
||||||
|
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="spacy-nlp-pipeline"></i>
|
||||||
|
<br>
|
||||||
|
<b class="service-color-text text-darken" data-service="spacy-nlp-pipeline">Natural Language Processing</b>
|
||||||
|
<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 center-align hoverable" style="position: relative;">
|
||||||
|
<a href="{{ url_for('services.corpus_analysis') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
|
||||||
|
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="corpus-analysis"></i>
|
||||||
|
<br>
|
||||||
|
<b class="service-color-text text-darken" data-service="corpus-analysis">Corpus analysis</b>
|
||||||
|
<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 class="modal-footer">
|
||||||
|
<a class="btn-flat modal-close">Close</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,5 +1,8 @@
|
|||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<ul class="dropdown-content" id="nav-account-dropdown-content">
|
<ul class="dropdown-content" id="nav-account-dropdown-content">
|
||||||
|
<li><a href="#!">Logged in as {{ current_user.username }}<br><{{ current_user.email }}></a></li>
|
||||||
|
<li class="divider" tabindex="-1"></li>
|
||||||
|
<li><a href="{{ url_for('users.user', user_id=current_user.id) }}"><i class="material-icons">person</i>Your profile</a></li>
|
||||||
<li><a href="{{ url_for('settings.settings') }}"><i class="material-icons left">settings</i>Settings</a></li>
|
<li><a href="{{ url_for('settings.settings') }}"><i class="material-icons left">settings</i>Settings</a></li>
|
||||||
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons left">logout</i>Log out</a></li>
|
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons left">logout</i>Log out</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
{% if current_user.is_authenticated and not current_user.terms_of_use_accepted %}
|
{% if current_user.is_authenticated and not current_user.terms_of_use_accepted %}
|
||||||
{% include "_base/_modals/terms_of_use.html.j2" %}
|
{% include "_base/_modals/terms_of_use.html.j2" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "_base/_modals/data-processing-and-analysis.html.j2" %}
|
||||||
|
@ -1,38 +1,95 @@
|
|||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<!-- menu icon -->
|
{# menu icon #}
|
||||||
<!-- small/medium devices -->
|
{# shown for small/medium devices #}
|
||||||
<a href="#!" class="sidenav-trigger" data-target="sidenav"><i class="material-icons">menu</i></a>
|
<a href="#!" class="sidenav-trigger" data-target="sidenav"><i class="material-icons">menu</i></a>
|
||||||
|
|
||||||
|
{# nopaque logo #}
|
||||||
|
{# shown for large devices #}
|
||||||
|
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%;">
|
||||||
|
<img src="{{ url_for('static', filename='images/nopaque_-_logo.png') }}" alt="" class="mx-3 py-3" style="height: 100%;">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{# left aligned navigation items #}
|
||||||
|
{# shown for large devices #}
|
||||||
|
<ul class="hide-on-med-and-down" style="margin-left: calc(57px + 1.5rem);">
|
||||||
|
{# dashboard #}
|
||||||
|
<li>
|
||||||
|
<a href="{{ url_for('main.dashboard') }}">
|
||||||
|
<i class="material-icons left">dashboard</i>
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{# processes & services #}
|
||||||
|
<li>
|
||||||
|
<a href="#data-processing-and-analysis-modal" class="modal-trigger">
|
||||||
|
<i class="material-icons left">miscellaneous_services</i>
|
||||||
|
Data Processing & Analysis
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{# contributions #}
|
||||||
|
<li>
|
||||||
|
<a href="{{ url_for('contributions.index') }}">
|
||||||
|
<i class="material-icons left">new_label</i>
|
||||||
|
Contributions
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{# social #}
|
||||||
|
<li>
|
||||||
|
<a href="{{ url_for('main.social') }}">
|
||||||
|
<i class="material-icons left">groups</i>
|
||||||
|
Social
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
{# nopaque logo+wordmark+slogan #}
|
||||||
|
{# shown for large devices #}
|
||||||
|
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%;">
|
||||||
|
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark+slogan.png') }}" alt="" class="mx-3 py-3" style="height: 100%;">
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- nopaque logo+wordmark -->
|
{# nopaque logo+wordmark #}
|
||||||
<!-- small/medium devices -->
|
{# small/medium devices #}
|
||||||
<a href="{{ url_for('main.index') }}" class="brand-logo center hide-on-large-only" style="height: 100%;">
|
<a href="{{ url_for('main.index') }}" class="brand-logo center hide-on-large-only" style="height: 100%;">
|
||||||
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark.png') }}" alt="" class="py-3" style="height: 100%;">
|
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark.png') }}" alt="" class="py-3" style="height: 100%;">
|
||||||
</a>
|
</a>
|
||||||
<!-- large devices -->
|
|
||||||
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="width: 300px; height: 100%;">
|
|
||||||
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark.png') }}" alt="" class="py-3 ml-4" style="height: 100%;">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- right aligned navigation links -->
|
{# right aligned navigation items #}
|
||||||
<!-- large devices -->
|
{# large devices #}
|
||||||
<ul class="right hide-on-med-and-down" style="height: 64px;">
|
<ul class="right hide-on-med-and-down" style="height: 64px;">
|
||||||
|
{# manual #}
|
||||||
|
<li class="tooltipped" data-position="bottom" data-tooltip="Manual">
|
||||||
|
<a href="{{ url_for('main.manual') }}">
|
||||||
|
<i class="material-icons">help_outline</i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{# news #}
|
||||||
|
<li class="tooltipped" data-position="bottom" data-tooltip="News">
|
||||||
|
<a href="{{ url_for('main.news') }}">
|
||||||
|
<i class="material-icons">email</i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<!-- avatar, username and email -->
|
{# avatar #}
|
||||||
<li style="height: 100%;">
|
<li style="height: 100%;">
|
||||||
<a href="#!" class="dropdown-trigger no-autoinit" data-target="nav-account-dropdown-content" id="nav-account-dropdown-trigger" style="height: 100%;">
|
<a href="#!" class="dropdown-trigger no-autoinit" data-target="nav-account-dropdown-content" id="nav-account-dropdown-trigger" style="height: 100%;">
|
||||||
<img src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt="" class="left circle py-3" style="height: 100%;">
|
<img src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt="" class="circle py-3" style="height: 100%;">
|
||||||
<span class="ml-2">{{ current_user.username }} ({{ current_user.email }})</span>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<!-- log in -->
|
{# log in #}
|
||||||
<li {% if request.path == url_for('auth.login') %}class="active"{% endif %}>
|
<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>
|
<a href="{{ url_for('auth.login') }}">Log in</a>
|
||||||
</li>
|
</li>
|
||||||
<!-- register -->
|
{# register #}
|
||||||
<li {% if request.path == url_for('auth.register') %}class="active"{% endif %}>
|
<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>
|
<a href="{{ url_for('auth.register') }}" class="waves-effect waves-light btn primary-color lighten">Register</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<ul class="sidenav sidenav-fixed" id="sidenav">
|
<ul class="sidenav {{ 'sidenav-fixed' if sidenav_fixed else '' }}" id="sidenav">
|
||||||
{# user view #}
|
{# user view #}
|
||||||
{# shown for small/medium devices #}
|
<li>
|
||||||
<li class="hide-on-large-only">
|
|
||||||
<div class="user-view">
|
<div class="user-view">
|
||||||
<div class="background primary-color"></div>
|
<div class="background primary-color"></div>
|
||||||
<a><img class="circle" src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt=""></a>
|
<a><img class="circle" src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt=""></a>
|
||||||
@ -11,34 +10,28 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
{# general items #}
|
{# general items #}
|
||||||
{% if current_user.can('USE_API') %}
|
<li {% if request.path == url_for('main.news') %}class="active"{% endif %}>
|
||||||
<li>
|
|
||||||
<a class="waves-effect" href="{{ url_for('apifairy.docs') }}"><i class="material-icons">api</i>API</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
<li>
|
|
||||||
<a class="waves-effect" href="{{ url_for('main.manual') }}"><i class="material-icons">school</i>Manual</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="waves-effect" href="{{ url_for('main.news') }}"><i class="material-icons">email</i>News</a>
|
<a class="waves-effect" href="{{ url_for('main.news') }}"><i class="material-icons">email</i>News</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li {% if request.path == url_for('main.dashboard') %}class="active"{% endif %}>
|
||||||
{# dashboard items #}
|
<a class="waves-effect" href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a>
|
||||||
<li><div class="divider"></div></li>
|
|
||||||
<li><a class="subheader">Dashboard</a></li>
|
|
||||||
<li {% if request.path == url_for('corpora.corpora') %}class="active"{% endif %}>
|
|
||||||
<a class="waves-effect" href="{{ url_for('corpora.corpora') }}"><i class="nopaque-icons">I</i>My Corpora</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li {% if request.path == url_for('jobs.jobs') %}class="active"{% endif %}>
|
<li {% if request.path == url_for('contributions.index') %}class="active"{% endif %}>
|
||||||
<a class="waves-effect" href="{{ url_for('jobs.jobs') }}"><i class="nopaque-icons">J</i>My Jobs</a>
|
<a href="{{ url_for('contributions.index') }}">
|
||||||
|
<i class="material-icons left">new_label</i>
|
||||||
|
Contributions
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li {% if request.path == url_for('main.social') %}class="active"{% endif %}>
|
||||||
<a class="waves-effect" href="{{ url_for('contributions.index') }}"><i class="material-icons">new_label</i>My Contributions</a>
|
<a class="waves-effect" href="{{ url_for('main.social') }}"><i class="material-icons">groups</i>Social</a>
|
||||||
|
</li>
|
||||||
|
<li {% if request.path == url_for('main.manual') %}class="active"{% endif %}>
|
||||||
|
<a class="waves-effect" href="{{ url_for('main.manual') }}"><i class="material-icons">help_outline</i>Manual</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{# processes & services items #}
|
{# processes & services items #}
|
||||||
<li><div class="divider"></div></li>
|
<li><div class="divider"></div></li>
|
||||||
<li><a class="subheader">Processes & Services</a></li>
|
<li><a class="subheader">Data Processing & Analysis</a></li>
|
||||||
<li class="service-color service-color-border border-darken" data-service="file-setup-pipeline" style="border-left: 10px solid;">
|
<li class="service-color service-color-border border-darken" data-service="file-setup-pipeline" style="border-left: 10px solid;">
|
||||||
<a class="waves-effect" href="{{ url_for('services.file_setup_pipeline') }}"><i class="nopaque-icons service-icons" data-service="file-setup-pipeline"></i>File setup</a>
|
<a class="waves-effect" href="{{ url_for('services.file_setup_pipeline') }}"><i class="nopaque-icons service-icons" data-service="file-setup-pipeline"></i>File setup</a>
|
||||||
</li>
|
</li>
|
||||||
@ -57,17 +50,17 @@
|
|||||||
<a class="waves-effect" href="{{ url_for('services.corpus_analysis') }}"><i class="nopaque-icons service-icons" data-service="corpus-analysis"></i>Corpus Analysis</a>
|
<a class="waves-effect" href="{{ url_for('services.corpus_analysis') }}"><i class="nopaque-icons service-icons" data-service="corpus-analysis"></i>Corpus Analysis</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{# social items #}
|
{# account items #}
|
||||||
<li><div class="divider"></div></li>
|
<li class="hide-on-large-only"><div class="divider"></div></li>
|
||||||
<li><a class="subheader">Social</a></li>
|
<li class="hide-on-large-only"><a class="subheader">Account</a></li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('users.user', user_id=current_user.id) }}"><i class="material-icons">person</i>My Profile</a>
|
<a href="{{ url_for('users.user', user_id=current_user.id) }}"><i class="material-icons">person</i>My Profile</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="hide-on-large-only">
|
||||||
<a class="waves-effect" href="{{ url_for('main.social_area', _anchor='public-users') }}"><i class="material-icons">group</i>Public Users</a>
|
<a class="waves-effect" href="{{ url_for('settings.settings') }}"><i class="material-icons">settings</i>Settings</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="hide-on-large-only">
|
||||||
<a class="waves-effect" href="{{ url_for('main.social_area', _anchor='public-corpora') }}"><i class="nopaque-icons">I</i>Public Corpora</a>
|
<a class="waves-effect" href="{{ url_for('auth.logout') }}"><i class="material-icons">logout</i>Log out</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{# administration items #}
|
{# administration items #}
|
||||||
@ -81,14 +74,4 @@
|
|||||||
<a class="waves-effect" href="{{ url_for('admin.users') }}"><i class="material-icons">manage_accounts</i>Users</a>
|
<a class="waves-effect" href="{{ url_for('admin.users') }}"><i class="material-icons">manage_accounts</i>Users</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# account items #}
|
|
||||||
<li class="hide-on-large-only"><div class="divider"></div></li>
|
|
||||||
<li class="hide-on-large-only"><a class="subheader">Account</a></li>
|
|
||||||
<li class="hide-on-large-only">
|
|
||||||
<a class="waves-effect" href="{{ url_for('settings.settings') }}"><i class="material-icons">settings</i>Settings</a>
|
|
||||||
</li>
|
|
||||||
<li class="hide-on-large-only">
|
|
||||||
<a class="waves-effect" href="{{ url_for('auth.logout') }}"><i class="material-icons">logout</i>Log out</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if sidenav_fixed is not defined %}
|
{% if sidenav_fixed is not defined %}
|
||||||
{% set sidenav_fixed = current_user.is_authenticated %}
|
{% set sidenav_fixed = false %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if sticky_footer is not defined %}
|
{% if sticky_footer is not defined %}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
{% extends "base.html.j2" %}
|
{% extends "base.html.j2" %}
|
||||||
{% import "wtf.html.j2" as wtf %}
|
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -12,14 +11,24 @@
|
|||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="tesseract-ocr-pipeline-model-list" data-user-id="{{ current_user.hashid }}"></div>
|
<div class="spacy-nlp-pipeline-model-list" data-user-id="{{ current_user.hashid }}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action right-align">
|
<div class="card-action right-align">
|
||||||
<a href="{{ url_for('.create') }}" class="btn waves-effect waves-light"><i class="material-icons left">add</i>Create</a>
|
<a href="{{ url_for('.spacy_nlp_pipeline_models.create') }}" class="btn waves-effect waves-light"><i class="material-icons left">add</i>Create</a>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="tesseract-ocr-pipeline-model-list" data-user-id="{{ current_user.hashid }}"></div>
|
||||||
|
</div>
|
||||||
|
<div class="card-action right-align">
|
||||||
|
<a href="{{ url_for('.tesseract_ocr_pipeline_models.create') }}" class="btn waves-effect waves-light"><i class="material-icons left">add</i>Create</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock page_content %}
|
{% endblock page_content %}
|
@ -41,97 +41,10 @@
|
|||||||
<div class="job-list" data-user-id="{{ current_user.hashid }}"></div>
|
<div class="job-list" data-user-id="{{ current_user.hashid }}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action right-align">
|
<div class="card-action right-align">
|
||||||
<p><a class="btn modal-trigger waves-effect waves-light" data-target="create-job-modal">Create job<i class="material-icons right">add</i></a></p>
|
<p><a href="#data-processing-and-analysis-modal" class="btn modal-trigger waves-effect waves-light">Create job<i class="material-icons right">add</i></a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col s12" id="contributions">
|
|
||||||
<h2>My Contributions</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col s4">
|
|
||||||
<div class="card extension-selector hoverable service-color" data-service="tesseract-ocr-pipeline">
|
|
||||||
<a href="{{ url_for('tesseract_ocr_pipeline_models.index') }}" style="position: absolute; width: 100%; height: 100%;"></a>
|
|
||||||
<div class="card-content">
|
|
||||||
<span class="card-title">Tesseract OCR Pipeline Models</span>
|
|
||||||
<p>Here you can see and edit the models that you have created. You can also create new models.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col s4">
|
|
||||||
<div class="card extension-selector hoverable service-color" data-service="spacy-nlp-pipeline">
|
|
||||||
<a href="{{ url_for('spacy_nlp_pipeline_models.index') }}" style="position: absolute; width: 100%; height: 100%;"></a>
|
|
||||||
<div class="card-content">
|
|
||||||
<span class="card-title">SpaCy NLP Pipeline Models</span>
|
|
||||||
<p>Here you can see and edit the models that you have created. You can also create new models.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
|
|
||||||
<div class="col s4">
|
|
||||||
<div class="card extension-selector hoverable service-color" data-service="transkribus-htr-pipeline">
|
|
||||||
<a href="{{ url_for('transkribus_htr_pipeline_models.index') }}" style="position: absolute; width: 100%; height: 100%;"></a>
|
|
||||||
<div class="card-content">
|
|
||||||
<span class="card-title">Transkribus HTR Pipeline Models</span>
|
|
||||||
<p>Here you can see and edit the models that you have created. You can also create new models.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock page_content %}
|
|
||||||
|
|
||||||
{% block modals %}
|
|
||||||
{{ super() }}
|
|
||||||
<div id="create-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.file_setup_pipeline') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
|
||||||
<i class="nopaque-icons service-color darken service-icons" data-service="file-setup-pipeline"></i>
|
|
||||||
</a>
|
|
||||||
<br><br>
|
|
||||||
<p class="service-color-text darken" data-service="file-setup-pipeline"><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.</p>
|
|
||||||
<a href="{{ url_for('services.file_setup_pipeline') }}" class="waves-effect waves-light btn service-color darken" data-service="file-setup-pipeline">Create Job</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m4">
|
|
||||||
<div class="card-panel center-align hoverable">
|
|
||||||
<br>
|
|
||||||
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
|
||||||
<i class="nopaque-icons service-color darken service-icons" data-service="tesseract-ocr-pipeline" style="font-size: 2.5rem;"></i>
|
|
||||||
</a>
|
|
||||||
<br><br>
|
|
||||||
<p class="service-color-text darken" data-service="tesseract-ocr-pipeline"><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.tesseract_ocr_pipeline') }}" class="waves-effect waves-light btn service-color darken" data-service="tesseract-ocr-pipeline">Create Job</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m4">
|
|
||||||
<div class="card-panel center-align hoverable">
|
|
||||||
<br>
|
|
||||||
<a href="{{ url_for('services.spacy_nlp_pipeline') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
|
||||||
<i class="nopaque-icons service-color darken service-icons" data-service="spacy-nlp-pipeline" style="font-size: 2.5rem;"></i>
|
|
||||||
</a>
|
|
||||||
<br><br>
|
|
||||||
<p class="service-color-text darken" data-service="spacy-nlp-pipeline"><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.spacy_nlp_pipeline') }}" class="waves-effect waves-light btn service-color darken" data-service="spacy-nlp-pipeline">Create Job</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
{% endblock page_content %}
|
||||||
<a class="btn-flat modal-close waves-effect waves-light">Close</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock modals %}
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
{% extends "base.html.j2" %}
|
|
||||||
{% import "wtf.html.j2" as wtf %}
|
|
||||||
|
|
||||||
{% block page_content %}
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s12">
|
|
||||||
<h1 id="title">{{ title }}</h1>
|
|
||||||
<p>Here you can see and edit the models that you have created. You can also create new models.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col s12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="spacy-nlp-pipeline-model-list" data-user-id="{{ current_user.hashid }}"></div>
|
|
||||||
</div>
|
|
||||||
<div class="card-action right-align">
|
|
||||||
<a href="{{ url_for('.create') }}" class="btn waves-effect waves-light"><i class="material-icons left">add</i>Create</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock page_content %}
|
|
Loading…
Reference in New Issue
Block a user