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
c0d015acd8
@ -1,5 +1,5 @@
|
|||||||
from flask import flash, redirect, render_template, url_for
|
from flask import flash, redirect, render_template, url_for
|
||||||
from flask_login import login_required, login_user
|
from flask_login import current_user, login_required, login_user
|
||||||
from app.auth.forms import LoginForm
|
from app.auth.forms import LoginForm
|
||||||
from app.models import User
|
from app.models import User
|
||||||
from . import bp
|
from . import bp
|
||||||
@ -27,7 +27,11 @@ def faq():
|
|||||||
@bp.route('/dashboard')
|
@bp.route('/dashboard')
|
||||||
@login_required
|
@login_required
|
||||||
def dashboard():
|
def dashboard():
|
||||||
return render_template('main/dashboard.html.j2', title='Dashboard')
|
users = [
|
||||||
|
u.to_json_serializeable(filter_by_privacy_settings=True, include_avatar_relationship=True) for u
|
||||||
|
in User.query.filter(User.is_public == True, User.id != current_user.id).all()
|
||||||
|
]
|
||||||
|
return render_template('main/dashboard.html.j2', title='Dashboard', users=users)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/dashboard2')
|
@bp.route('/dashboard2')
|
||||||
|
@ -256,8 +256,7 @@ class Avatar(HashidMixin, FileMixin, db.Model):
|
|||||||
# Primary key
|
# Primary key
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
# Foreign keys
|
# Foreign keys
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
|
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), unique=True)
|
||||||
# Backrefs: user: User
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
@ -270,6 +269,11 @@ class Avatar(HashidMixin, FileMixin, db.Model):
|
|||||||
current_app.logger.error(e)
|
current_app.logger.error(e)
|
||||||
db.session.delete(self)
|
db.session.delete(self)
|
||||||
|
|
||||||
|
def to_json_serializeable(self, backrefs=False, relationships=False):
|
||||||
|
json_serializeable = {
|
||||||
|
'id': self.id
|
||||||
|
}
|
||||||
|
return json_serializeable
|
||||||
|
|
||||||
class User(HashidMixin, UserMixin, db.Model):
|
class User(HashidMixin, UserMixin, db.Model):
|
||||||
__tablename__ = 'users'
|
__tablename__ = 'users'
|
||||||
@ -536,7 +540,16 @@ class User(HashidMixin, UserMixin, db.Model):
|
|||||||
self.profile_privacy_settings = 0
|
self.profile_privacy_settings = 0
|
||||||
#endregion Profile Privacy settings
|
#endregion Profile Privacy settings
|
||||||
|
|
||||||
def to_json_serializeable(self, backrefs=False, relationships=False):
|
def to_json_serializeable(
|
||||||
|
self, backrefs=False,
|
||||||
|
relationships=False,
|
||||||
|
filter_by_privacy_settings=False,
|
||||||
|
include_corpus_relationships=False,
|
||||||
|
include_job_relationships=False,
|
||||||
|
include_tesseract_ocr_pipeline_model_relationships=False,
|
||||||
|
include_spacy_nlp_pipeline_model_relationships=False,
|
||||||
|
include_avatar_relationship=False
|
||||||
|
):
|
||||||
json_serializeable = {
|
json_serializeable = {
|
||||||
'id': self.hashid,
|
'id': self.hashid,
|
||||||
'confirmed': self.confirmed,
|
'confirmed': self.confirmed,
|
||||||
@ -562,23 +575,39 @@ class User(HashidMixin, UserMixin, db.Model):
|
|||||||
if backrefs:
|
if backrefs:
|
||||||
json_serializeable['role'] = \
|
json_serializeable['role'] = \
|
||||||
self.role.to_json_serializeable(backrefs=True)
|
self.role.to_json_serializeable(backrefs=True)
|
||||||
if relationships:
|
if relationships or include_corpus_relationships:
|
||||||
json_serializeable['corpora'] = {
|
json_serializeable['corpora'] = {
|
||||||
x.hashid: x.to_json_serializeable(relationships=True)
|
x.hashid: x.to_json_serializeable(relationships=True)
|
||||||
for x in self.corpora
|
for x in self.corpora
|
||||||
}
|
}
|
||||||
|
if relationships or include_job_relationships:
|
||||||
json_serializeable['jobs'] = {
|
json_serializeable['jobs'] = {
|
||||||
x.hashid: x.to_json_serializeable(relationships=True)
|
x.hashid: x.to_json_serializeable(relationships=True)
|
||||||
for x in self.jobs
|
for x in self.jobs
|
||||||
}
|
}
|
||||||
|
if relationships or include_tesseract_ocr_pipeline_model_relationships:
|
||||||
json_serializeable['tesseract_ocr_pipeline_models'] = {
|
json_serializeable['tesseract_ocr_pipeline_models'] = {
|
||||||
x.hashid: x.to_json_serializeable(relationships=True)
|
x.hashid: x.to_json_serializeable(relationships=True)
|
||||||
for x in self.tesseract_ocr_pipeline_models
|
for x in self.tesseract_ocr_pipeline_models
|
||||||
}
|
}
|
||||||
|
if relationships or include_spacy_nlp_pipeline_model_relationships:
|
||||||
json_serializeable['spacy_nlp_pipeline_models'] = {
|
json_serializeable['spacy_nlp_pipeline_models'] = {
|
||||||
x.hashid: x.to_json_serializeable(relationships=True)
|
x.hashid: x.to_json_serializeable(relationships=True)
|
||||||
for x in self.spacy_nlp_pipeline_models
|
for x in self.spacy_nlp_pipeline_models
|
||||||
}
|
}
|
||||||
|
if relationships or include_avatar_relationship:
|
||||||
|
json_serializeable['avatar'] = (
|
||||||
|
None if self.avatar is None
|
||||||
|
else self.avatar.to_json_serializeable(relationships=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
if filter_by_privacy_settings:
|
||||||
|
if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL):
|
||||||
|
json_serializeable.pop('email')
|
||||||
|
if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN):
|
||||||
|
json_serializeable.pop('last_seen')
|
||||||
|
if not self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE):
|
||||||
|
json_serializeable.pop('member_since')
|
||||||
return json_serializeable
|
return json_serializeable
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,6 @@ def delete_avatar(avatar_id, user_id):
|
|||||||
def _delete_avatar(app, avatar_id):
|
def _delete_avatar(app, avatar_id):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
avatar_file = Avatar.query.get(avatar_id)
|
avatar_file = Avatar.query.get(avatar_id)
|
||||||
print(avatar_file)
|
|
||||||
avatar_file.delete()
|
avatar_file.delete()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
thread = Thread(
|
thread = Thread(
|
||||||
|
79
app/static/js/RessourceLists/PublicUserList.js
Normal file
79
app/static/js/RessourceLists/PublicUserList.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
class PublicUserList extends RessourceList {
|
||||||
|
static autoInit() {
|
||||||
|
for (let publicUserListElement of document.querySelectorAll('.public-user-list:not(.no-autoinit)')) {
|
||||||
|
new PublicUserList(publicUserListElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static options = {
|
||||||
|
initialHtmlGenerator: (id) => {
|
||||||
|
console.log(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 user</label>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width:15%;"></th>
|
||||||
|
<th>Username</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list"></tbody>
|
||||||
|
</table>
|
||||||
|
<ul class="pagination"></ul>
|
||||||
|
`.trim();
|
||||||
|
},
|
||||||
|
item: `
|
||||||
|
<tr class="clickable hoverable">
|
||||||
|
<td><img alt="user-image" class="circle responsive-img avatar" style="width:80%"></td>
|
||||||
|
<td><span class="username"></span></td>
|
||||||
|
<td class="right-align">
|
||||||
|
<a class="action-button btn-floating waves-effect waves-light" data-action="view"><i class="material-icons">send</i></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`.trim(),
|
||||||
|
ressourceMapper: (user) => {
|
||||||
|
return {
|
||||||
|
'id': user.id,
|
||||||
|
'member-since': user.member_since,
|
||||||
|
'avatar': `/static/images/user_avatar.png`,
|
||||||
|
'username': user.username
|
||||||
|
};
|
||||||
|
},
|
||||||
|
sortArgs: ['member-since', {order: 'desc'}],
|
||||||
|
valueNames: [
|
||||||
|
{data: ['id']},
|
||||||
|
{data: ['member-since']},
|
||||||
|
{name: 'avatar', attr: 'src'},
|
||||||
|
'username'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(listElement, options = {}) {
|
||||||
|
super(listElement, {...PublicUserList.options, ...options});
|
||||||
|
}
|
||||||
|
|
||||||
|
init(users) {
|
||||||
|
super._init(Object.values(users));
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick(event) {
|
||||||
|
let actionButtonElement = event.target.closest('.action-button');
|
||||||
|
let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action;
|
||||||
|
let publicUserElement = event.target.closest('tr');
|
||||||
|
let publicUserId = publicUserElement.dataset.id;
|
||||||
|
switch (action) {
|
||||||
|
case 'view': {
|
||||||
|
window.location.href = `/profile/${publicUserId}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,8 @@ class RessourceList {
|
|||||||
JobList.autoInit();
|
JobList.autoInit();
|
||||||
JobInputList.autoInit();
|
JobInputList.autoInit();
|
||||||
JobResultList.autoInit();
|
JobResultList.autoInit();
|
||||||
|
PublicCorporaList.autoInit();
|
||||||
|
PublicUserList.autoInit();
|
||||||
SpaCyNLPPipelineModelList.autoInit();
|
SpaCyNLPPipelineModelList.autoInit();
|
||||||
TesseractOCRPipelineModelList.autoInit();
|
TesseractOCRPipelineModelList.autoInit();
|
||||||
UserList.autoInit();
|
UserList.autoInit();
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
'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/PublicUserList.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',
|
||||||
|
@ -22,11 +22,7 @@
|
|||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script>
|
<script>
|
||||||
for (let user of {{ json_users|tojson }}) {
|
|
||||||
if (user.id in app.data.users) {continue;}
|
|
||||||
app.data.users[user.id] = user;
|
|
||||||
}
|
|
||||||
let userList = new UserList(document.querySelector('.user-list'));
|
let userList = new UserList(document.querySelector('.user-list'));
|
||||||
userList.init(app.data.users);
|
userList._init({{ json_users|tojson }});
|
||||||
</script>
|
</script>
|
||||||
{% endblock scripts %}
|
{% endblock scripts %}
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span class="card-title">Other users and groups</span>
|
<span class="card-title">Other users and groups</span>
|
||||||
<p>Find other users and follow them to see their corpora and groups.</p>
|
<p>Find other users and follow them to see their corpora and groups.</p>
|
||||||
|
<div class="public-user-list no-autoinit"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -115,3 +116,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock modals %}
|
{% endblock modals %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
|
let publicUserList = new PublicUserList(document.querySelector('.public-user-list'));
|
||||||
|
publicUserList._init({{ users|tojson }});
|
||||||
|
</script>
|
||||||
|
{% endblock scripts %}
|
||||||
|
Loading…
Reference in New Issue
Block a user