mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
Merge branch 'profile-page' into development
This commit is contained in:
commit
85330a42f7
@ -10,7 +10,7 @@ from flask import (
|
|||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
import os
|
import os
|
||||||
from app import db
|
from app import db
|
||||||
from app.models import Avatar
|
from app.models import Avatar, User
|
||||||
from . import bp
|
from . import bp
|
||||||
from .forms import (
|
from .forms import (
|
||||||
EditProfileSettingsForm
|
EditProfileSettingsForm
|
||||||
@ -22,14 +22,15 @@ def before_request():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@bp.route('')
|
@bp.route('/<hashid:user_id>')
|
||||||
def profile():
|
def profile(user_id):
|
||||||
|
user = User.query.get_or_404(user_id)
|
||||||
return render_template('profile/profile_page.html.j2',
|
return render_template('profile/profile_page.html.j2',
|
||||||
user=current_user)
|
user=user)
|
||||||
|
|
||||||
@bp.route('/avatars/<hashid:avatar_id>')
|
@bp.route('/<hashid:user_id>/avatars/<hashid:avatar_id>')
|
||||||
def avatar_download(avatar_id):
|
def avatar_download(user_id, avatar_id):
|
||||||
avatar_file = Avatar.query.get_or_404(avatar_id)
|
avatar_file = Avatar.query.filter_by(user_id = user_id, id = avatar_id).first_or_404()
|
||||||
if not (avatar_file and avatar_file.filename):
|
if not (avatar_file and avatar_file.filename):
|
||||||
abort(404)
|
abort(404)
|
||||||
return send_from_directory(
|
return send_from_directory(
|
||||||
@ -40,8 +41,9 @@ def avatar_download(avatar_id):
|
|||||||
mimetype=avatar_file.mimetype
|
mimetype=avatar_file.mimetype
|
||||||
)
|
)
|
||||||
|
|
||||||
@bp.route('/edit-profile', methods=['GET', 'POST'])
|
@bp.route('/<hashid:user_id>/edit-profile', methods=['GET', 'POST'])
|
||||||
def edit_profile():
|
def edit_profile(user_id):
|
||||||
|
user = User.query.get_or_404(user_id)
|
||||||
edit_profile_settings_form = EditProfileSettingsForm(
|
edit_profile_settings_form = EditProfileSettingsForm(
|
||||||
current_user,
|
current_user,
|
||||||
data=current_user.to_json_serializeable(),
|
data=current_user.to_json_serializeable(),
|
||||||
@ -63,7 +65,8 @@ def edit_profile():
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
message = Markup(f'Profile settings updated')
|
message = Markup(f'Profile settings updated')
|
||||||
flash(message, 'success')
|
flash(message, 'success')
|
||||||
return redirect(url_for('.profile'))
|
return redirect(url_for('.profile', user_id=user.id))
|
||||||
return render_template('profile/edit_profile.html.j2',
|
return render_template('profile/edit_profile.html.j2',
|
||||||
edit_profile_settings_form=edit_profile_settings_form,
|
edit_profile_settings_form=edit_profile_settings_form,
|
||||||
|
user=user,
|
||||||
title='Edit Profile')
|
title='Edit Profile')
|
||||||
|
70
app/static/js/RessourceLists/PublicCorporaList.js
Normal file
70
app/static/js/RessourceLists/PublicCorporaList.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
class PublicCorporaList extends RessourceList {
|
||||||
|
static instances = [];
|
||||||
|
|
||||||
|
static getInstance(elem) {
|
||||||
|
return PublicCorporaList.instances.find((instance) => {
|
||||||
|
return instance.listjs.list === elem;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static autoInit() {
|
||||||
|
for (let publicCorporaListElement of document.querySelectorAll('.public-corpora-list:not(.no-autoinit)')) {
|
||||||
|
new PublicCorporaList(publicCorporaListElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static options = {
|
||||||
|
initialHtmlGenerator: (id) => {
|
||||||
|
return `
|
||||||
|
<div class="input-field">
|
||||||
|
<i class="material-icons prefix">search</i>
|
||||||
|
<input id="${id}-search" class="search" type="search"></input>
|
||||||
|
<label for="${id}-search">Search corpus</label>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list"></tbody>
|
||||||
|
</table>
|
||||||
|
<ul class="pagination"></ul>
|
||||||
|
`.trim();
|
||||||
|
},
|
||||||
|
item: `
|
||||||
|
<tr class="clickable hoverable">
|
||||||
|
<td><a class="btn-floating disabled"><i class="material-icons service-color darken" data-service="corpus-analysis">book</i></a></td>
|
||||||
|
<td><b class="title"></b></td>
|
||||||
|
<td><i class="description"></i></td>
|
||||||
|
</tr>
|
||||||
|
`.trim(),
|
||||||
|
ressourceMapper: (corpus) => {
|
||||||
|
return {
|
||||||
|
'id': corpus.id,
|
||||||
|
'creation-date': corpus.creation_date,
|
||||||
|
'description': corpus.description,
|
||||||
|
'title': corpus.title
|
||||||
|
};
|
||||||
|
},
|
||||||
|
sortArgs: ['creation-date', {order: 'desc'}],
|
||||||
|
valueNames: [
|
||||||
|
{data: ['id']},
|
||||||
|
{data: ['creation-date']},
|
||||||
|
'description',
|
||||||
|
'title'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(listElement, options = {}) {
|
||||||
|
super(listElement, {...PublicCorporaList.options, ...options});
|
||||||
|
PublicCorporaList.instances.push(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
init(user) {
|
||||||
|
this._init(user.corpora.is_public);
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ class RessourceList {
|
|||||||
JobList.autoInit();
|
JobList.autoInit();
|
||||||
JobInputList.autoInit();
|
JobInputList.autoInit();
|
||||||
JobResultList.autoInit();
|
JobResultList.autoInit();
|
||||||
|
PublicCorporaList.autoInit();
|
||||||
SpaCyNLPPipelineModelList.autoInit();
|
SpaCyNLPPipelineModelList.autoInit();
|
||||||
TesseractOCRPipelineModelList.autoInit();
|
TesseractOCRPipelineModelList.autoInit();
|
||||||
UserList.autoInit();
|
UserList.autoInit();
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
<ul class="dropdown-content" id="nav-more-dropdown">
|
<ul class="dropdown-content" id="nav-more-dropdown">
|
||||||
<li><a href="{{ url_for('main.user_manual') }}"><i class="material-icons left">help</i>Manual</a></li>
|
<li><a href="{{ url_for('main.user_manual') }}"><i class="material-icons left">help</i>Manual</a></li>
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<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>General settings</a></li>
|
||||||
|
<li><a href="{{ url_for('profile.edit_profile', user_id=current_user.id) }}"><i class="material-icons left">contact_page</i>Profile settings</a></li>
|
||||||
<li class="divider" tabindex="-1"></li>
|
<li class="divider" tabindex="-1"></li>
|
||||||
<li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
|
<li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
'js/RessourceLists/JobList.js',
|
'js/RessourceLists/JobList.js',
|
||||||
'js/RessourceLists/JobInputList.js',
|
'js/RessourceLists/JobInputList.js',
|
||||||
'js/RessourceLists/JobResultList.js',
|
'js/RessourceLists/JobResultList.js',
|
||||||
|
'js/RessourceLists/PublicCorporaList.js',
|
||||||
'js/RessourceLists/SpacyNLPPipelineModelList.js',
|
'js/RessourceLists/SpacyNLPPipelineModelList.js',
|
||||||
'js/RessourceLists/TesseractOCRPipelineModelList.js',
|
'js/RessourceLists/TesseractOCRPipelineModelList.js',
|
||||||
'js/RessourceLists/UserList.js'
|
'js/RessourceLists/UserList.js'
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div class="background primary-color"></div>
|
<div class="background primary-color"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s2">
|
<div class="col s2">
|
||||||
<a href="{{ url_for('profile.profile') }}">
|
<a href="{{ url_for('profile.profile', user_id=current_user.id) }}">
|
||||||
<i class="material-icons" style="color:white; font-size:3em; margin-top: 25px; margin-left:-15px;">account_circle</i></div>
|
<i class="material-icons" style="color:white; font-size:3em; margin-top: 25px; margin-left:-15px;">account_circle</i></div>
|
||||||
</a>
|
</a>
|
||||||
<div class="col s10">
|
<div class="col s10">
|
||||||
@ -14,12 +14,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="{{ url_for('main.index') }}">nopaque</a></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="{{ url_for('main.news') }}"><i class="material-icons left">email</i>News</a></li>
|
||||||
<li><a href="{{ url_for('main.user_manual') }}"><i class="material-icons">help</i>Manual</a></li>
|
<li><a href="{{ url_for('main.user_manual') }}"><i class="material-icons">help</i>Manual</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') }}"><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='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><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="nopaque-icons">J</i>My Jobs</a></li>
|
||||||
|
<li><a href="{{ url_for('main.dashboard', _anchor='social') }}" style="padding-left: 47px;"><i class="material-icons">groups</i>Social</a></li>
|
||||||
<li><a href="{{ url_for('contributions.contributions') }}"><i class="material-icons">new_label</i>Contribute</a></li>
|
<li><a href="{{ url_for('contributions.contributions') }}"><i class="material-icons">new_label</i>Contribute</a></li>
|
||||||
<li><div class="divider"></div></li>
|
<li><div class="divider"></div></li>
|
||||||
<li><a class="subheader">Processes & Services</a></li>
|
<li><a class="subheader">Processes & Services</a></li>
|
||||||
|
@ -42,6 +42,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col s12" id="social">
|
||||||
|
<h3>Social</h3>
|
||||||
|
<div class="col s6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="card-title">Other users and groups</span>
|
||||||
|
<p>Find other users and follow them to see their corpora and groups.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="card-title">Public corpora</span>
|
||||||
|
<p>Find public corpora</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock page_content %}
|
{% endblock page_content %}
|
||||||
|
@ -14,16 +14,24 @@
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
{{ edit_profile_settings_form.hidden_tag() }}
|
{{ edit_profile_settings_form.hidden_tag() }}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s1"></div>
|
<div class="col s5">
|
||||||
<div class="col s3">
|
<div class="row">
|
||||||
{% if current_user.avatar %}
|
<div class="col s1"></div>
|
||||||
<img src="{{ url_for('profile.avatar_download', avatar_id=current_user.avatar.id) }}" alt="user-image" class="circle responsive-img">
|
<div class="col s10">
|
||||||
{% else %}
|
{% if current_user.avatar %}
|
||||||
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img">
|
<img src="{{ url_for('profile.avatar_download', user_id=user.id, avatar_id=current_user.avatar.id) }}" alt="user-image" class="circle responsive-img">
|
||||||
{% endif %}
|
{% else %}
|
||||||
{{wtf.render_field(edit_profile_settings_form.avatar, accept='image/jpeg, image/png, image/gif', class='file-path validate')}}
|
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img">
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col s1"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
{{wtf.render_field(edit_profile_settings_form.avatar, accept='image/jpeg, image/png, image/gif', placeholder="Choose an image file")}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s1"></div>
|
|
||||||
<div class="col s7">
|
<div class="col s7">
|
||||||
{{ wtf.render_field(edit_profile_settings_form.username, material_icon='person') }}
|
{{ wtf.render_field(edit_profile_settings_form.username, material_icon='person') }}
|
||||||
{{ wtf.render_field(edit_profile_settings_form.email, material_icon='email') }}
|
{{ wtf.render_field(edit_profile_settings_form.email, material_icon='email') }}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<div class="col s1"></div>
|
<div class="col s1"></div>
|
||||||
<div class="col s4">
|
<div class="col s4">
|
||||||
{% if user.avatar %}
|
{% if user.avatar %}
|
||||||
<img src="{{ url_for('profile.avatar_download', avatar_id=user.avatar.id) }}" alt="user-image" class="circle responsive-img">
|
<img src="{{ url_for('profile.avatar_download', user_id=user.id, avatar_id=user.avatar.id) }}" alt="user-image" class="circle responsive-img">
|
||||||
{% else %}
|
{% else %}
|
||||||
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img">
|
<img src="{{ url_for('static', filename='images/user_avatar.png') }}" alt="user-image" class="circle responsive-img">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -67,12 +67,31 @@
|
|||||||
<p><i>Member since: {{ user.member_since.strftime('%Y-%m-%d') }}</i></p>
|
<p><i>Member since: {{ user.member_since.strftime('%Y-%m-%d') }}</i></p>
|
||||||
<p></p>
|
<p></p>
|
||||||
<br>
|
<br>
|
||||||
<a class="waves-effect waves-light btn-small" href="{{ url_for('profile.edit_profile') }}">Edit profile</a>
|
{% if current_user.is_authenticated and current_user.id == user.id %}
|
||||||
|
<a class="waves-effect waves-light btn-small" href="{{ url_for('profile.edit_profile', user_id=user.id) }}">Edit profile</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<h4>Groups</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<h4>Public corpora</h4>
|
||||||
|
<div class="public-corpora-list" data-user-id="{{ user.hashid }}"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock page_content %}
|
{% endblock page_content %}
|
||||||
|
Loading…
Reference in New Issue
Block a user