From 020de69e454cfb8944bb8b8dc69505b6dcf7d8b3 Mon Sep 17 00:00:00 2001 From: Patrick Jentsch <p.jentsch@uni-bielefeld.de> Date: Mon, 27 Mar 2023 10:22:43 +0200 Subject: [PATCH] settings update --- app/admin/routes.py | 154 ++++++++++++++++------ app/settings/json_routes.py | 27 +++- app/templates/admin/user.html.j2 | 2 +- app/templates/admin/user_settings.html.j2 | 6 + app/templates/settings/settings.html.j2 | 86 ++++++------ 5 files changed, 192 insertions(+), 83 deletions(-) create mode 100644 app/templates/admin/user_settings.html.j2 diff --git a/app/admin/routes.py b/app/admin/routes.py index 0b4ac8fc..899b4dfd 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -1,9 +1,13 @@ -from flask import flash, redirect, render_template, request, url_for +from flask import abort, flash, redirect, render_template, url_for from flask_breadcrumbs import register_breadcrumb -from app import db, hashids -from app.models import Corpus, Role, User, UserSettingJobStatusMailNotificationLevel -from app.settings.forms import EditNotificationsForm -from app.settings.forms import EditAccountForm +from app import db +from app.models import Avatar, Corpus, User +from app.settings.forms import ( + ChangePasswordForm, + EditNotificationsForm, + EditAccountForm, + EditProfileForm +) from . import bp from .forms import AdminEditUserForm from app.users.utils import ( @@ -54,52 +58,116 @@ def user(user_id): ) -@bp.route('/users/<hashid:user_id>/edit', methods=['GET', 'POST']) -@register_breadcrumb(bp, '.users.entity.edit', 'Edit', endpoint_arguments_constructor=user_eac) -def edit_user(user_id): +@bp.route('/users/<hashid:user_id>/settings', methods=['GET', 'POST']) +@register_breadcrumb(bp, '.users.entity.settings', '<i class="material-icons left">settings</i>Settings') +def user_settings(user_id): user = User.query.get_or_404(user_id) - admin_edit_user_form = AdminEditUserForm( - data={'confirmed': user.confirmed, 'role': user.role.hashid}, - prefix='admin-edit-user-form' - ) - edit_profile_settings_form = EditAccountForm( - user, - data=user.to_json_serializeable(), - prefix='edit-profile-settings-form' - ) - edit_notification_settings_form = EditNotificationsForm( - data=user.to_json_serializeable(), - prefix='edit-notification-settings-form' - ) - if (admin_edit_user_form.submit.data - and admin_edit_user_form.validate()): - user.confirmed = admin_edit_user_form.confirmed.data - role_id = hashids.decode(admin_edit_user_form.role.data) - user.role = Role.query.get(role_id) + # region forms + edit_account_form = EditAccountForm(user=user) + edit_profile_form = EditProfileForm(user=user) + change_password_form = ChangePasswordForm(user=user) + edit_notifications_form = EditNotificationsForm(user=user) + # endregion forms + # region handle edit profile settings form + if edit_account_form.validate_on_submit(): + user.email = edit_account_form.email.data + user.username = edit_account_form.username.data + db.session.commit() + flash('Profile settings updated') + return redirect(url_for('.user_settings')) + # endregion handle edit profile settings forms + # region handle edit public profile information form + if edit_profile_form.validate_on_submit(): + if edit_profile_form.avatar.data: + try: + Avatar.create( + edit_profile_form.avatar.data, + user=user + ) + except (AttributeError, OSError): + abort(500) + user.about_me = edit_profile_form.about_me.data + user.location = edit_profile_form.location.data + user.organization = edit_profile_form.organization.data + user.website = edit_profile_form.website.data + user.full_name = edit_profile_form.full_name.data db.session.commit() flash('Your changes have been saved') - return redirect(url_for('.edit_user', user_id=user.id)) - if (edit_profile_settings_form.submit.data - and edit_profile_settings_form.validate()): - user.email = edit_profile_settings_form.email.data - user.username = edit_profile_settings_form.username.data + return redirect(url_for('.user_settings')) + # endregion handle edit public profile information form + # region handle change_password_form POST + if change_password_form.validate_on_submit(): + user.password = change_password_form.new_password.data db.session.commit() flash('Your changes have been saved') - return redirect(url_for('.edit_user', user_id=user.id)) - if (edit_notification_settings_form.submit.data - and edit_notification_settings_form.validate()): + return redirect(url_for('.user_settings')) + # endregion handle change_password_form POST + # region handle edit_notification_settings_form POST + if edit_notifications_form.validate_on_submit(): user.setting_job_status_mail_notification_level = \ - UserSettingJobStatusMailNotificationLevel[ - edit_notification_settings_form.job_status_mail_notification_level.data # noqa - ] + edit_notifications_form.job_status_mail_notification_level.data db.session.commit() flash('Your changes have been saved') - return redirect(url_for('.edit_user', user_id=user.id)) + return redirect(url_for('.user_settings')) + # endregion handle edit_notification_settings_form POST return render_template( - 'admin/edit_user.html.j2', - admin_edit_user_form=admin_edit_user_form, - edit_profile_settings_form=edit_profile_settings_form, - edit_notification_settings_form=edit_notification_settings_form, - title='Edit user', + 'admin/user_settings.html.j2', + title='Settings', + change_password_form=change_password_form, + edit_account_form=edit_account_form, + edit_notifications_form=edit_notifications_form, + edit_profile_form=edit_profile_form, user=user ) + + + +# @bp.route('/users/<hashid:user_id>/edit', methods=['GET', 'POST']) +# @register_breadcrumb(bp, '.users.entity.edit', 'Edit', endpoint_arguments_constructor=user_eac) +# def edit_user(user_id): +# user = User.query.get_or_404(user_id) +# admin_edit_user_form = AdminEditUserForm( +# data={'confirmed': user.confirmed, 'role': user.role.hashid}, +# prefix='admin-edit-user-form' +# ) +# edit_profile_settings_form = EditAccountForm( +# user, +# data=user.to_json_serializeable(), +# prefix='edit-profile-settings-form' +# ) +# edit_notification_settings_form = EditNotificationsForm( +# data=user.to_json_serializeable(), +# prefix='edit-notification-settings-form' +# ) +# if (admin_edit_user_form.submit.data +# and admin_edit_user_form.validate()): +# user.confirmed = admin_edit_user_form.confirmed.data +# role_id = hashids.decode(admin_edit_user_form.role.data) +# user.role = Role.query.get(role_id) +# db.session.commit() +# flash('Your changes have been saved') +# return redirect(url_for('.edit_user', user_id=user.id)) +# if (edit_profile_settings_form.submit.data +# and edit_profile_settings_form.validate()): +# user.email = edit_profile_settings_form.email.data +# user.username = edit_profile_settings_form.username.data +# db.session.commit() +# flash('Your changes have been saved') +# return redirect(url_for('.edit_user', user_id=user.id)) +# if (edit_notification_settings_form.submit.data +# and edit_notification_settings_form.validate()): +# user.setting_job_status_mail_notification_level = \ +# UserSettingJobStatusMailNotificationLevel[ +# edit_notification_settings_form.job_status_mail_notification_level.data # noqa +# ] +# db.session.commit() +# flash('Your changes have been saved') +# return redirect(url_for('.edit_user', user_id=user.id)) +# return render_template( +# 'admin/edit_user.html.j2', +# admin_edit_user_form=admin_edit_user_form, +# edit_profile_settings_form=edit_profile_settings_form, +# edit_notification_settings_form=edit_notification_settings_form, +# title='Edit user', +# user=user +# ) diff --git a/app/settings/json_routes.py b/app/settings/json_routes.py index 77b421d9..c091174b 100644 --- a/app/settings/json_routes.py +++ b/app/settings/json_routes.py @@ -4,7 +4,7 @@ from threading import Thread import os from app import db from app.decorators import content_negotiation -from app.models import Avatar, User +from app.models import Avatar, User, ProfilePrivacySettings from . import bp @bp.route('/<hashid:user_id>', methods=['DELETE']) @@ -71,3 +71,28 @@ def update_user_is_public(user_id): 'category': 'corpus' } return response_data, 200 + + +# @bp.route('/<hashid:user_id>/profile-privacy-settings', methods=['PUT']) +# @login_required +# @content_negotiation(consumes='application/json', produces='application/json') +# def update_profile_privacy_settings(user_id): +# profile_privacy_settings = request.json +# if not isinstance(profile_privacy_settings, list): +# abort(400) +# for profile_privacy_setting in profile_privacy_settings: +# if not isinstance(profile_privacy_setting, str): +# abort(400) +# if not profile_privacy_setting in ProfilePrivacySettings.__members__: +# abort(400) +# user = User.query.get_or_404(user_id) +# user.is_public = is_public +# db.session.commit() +# response_data = { +# 'message': ( +# f'User "{user.username}" is now' +# f' {"public" if is_public else "private"}' +# ), +# 'category': 'corpus' +# } +# return response_data, 200 diff --git a/app/templates/admin/user.html.j2 b/app/templates/admin/user.html.j2 index 403828f2..dc5af986 100644 --- a/app/templates/admin/user.html.j2 +++ b/app/templates/admin/user.html.j2 @@ -45,7 +45,7 @@ </ul> </div> <div class="card-action right-align"> - <a class="btn waves-effect waves-light" href="{{ url_for('.edit_user', user_id=user.id) }}"><i class="material-icons left">edit</i>Edit</a> + <a class="btn waves-effect waves-light" href="{{ url_for('.user_settings', user_id=user.id) }}"><i class="material-icons left">edit</i>Edit</a> <a class="btn red modal-trigger waves-effect waves-light" data-target="delete-user-modal"><i class="material-icons left">delete</i>Delete</a> </div> </div> diff --git a/app/templates/admin/user_settings.html.j2 b/app/templates/admin/user_settings.html.j2 new file mode 100644 index 00000000..49d8ba4d --- /dev/null +++ b/app/templates/admin/user_settings.html.j2 @@ -0,0 +1,6 @@ +{% extends "settings/settings.html.j2" %} + +{% block page_content %} +{{ super() }} +ADMIN ADDITIONS +{% endblock page_content %} diff --git a/app/templates/settings/settings.html.j2 b/app/templates/settings/settings.html.j2 index b219d3e6..370a0312 100644 --- a/app/templates/settings/settings.html.j2 +++ b/app/templates/settings/settings.html.j2 @@ -19,26 +19,6 @@ <div class="col s8"> <br> <ul class="collapsible no-autoinit settings-collapsible"> - <li> - <div class="collapsible-header" style="justify-content: space-between;"> - <span>User Settings</span> - <i class="caret material-icons right">keyboard_arrow_right</i> - </div> - <div class="collapsible-body"> - <form method="POST" enctype="multipart/form-data"> - <div class="row"> - <div class="col s6"> - {{ edit_account_form.hidden_tag() }} - {{ wtf.render_field(edit_account_form.username, material_icon='person') }} - {{ wtf.render_field(edit_account_form.email, material_icon='email') }} - </div> - </div> - <div class="right-align"> - {{ wtf.render_field(edit_account_form.submit, material_icon='send') }} - </div> - </form> - </div> - </li> <li> <div class="collapsible-header" style="justify-content: space-between;"><span>Public Profile</span><i class="material-icons caret right">keyboard_arrow_right</i></div> <div class="collapsible-body"> @@ -57,6 +37,26 @@ <div class="divider"></div> <p>Show:</p> <div class="row"> + <div class="col s3"> + <label> + <input {% if user.has_profile_privacy_setting('SHOW_EMAIL') %}checked{% endif %} id="profile-show-email-checkbox" type="checkbox"> + <span>Email</span> + </label> + </div> + <div class="col s3"> + <label> + <input {% if user.has_profile_privacy_setting('SHOW_LAST_SEEN') %}checked{% endif %} id="profile-show-last-seen-checkbox" type="checkbox"> + <span>Last seen</span> + </label> + </div> + <div class="col s3"> + <label> + <input {% if user.has_profile_privacy_setting('SHOW_MEMBER_SINCE') %}checked{% endif %} id="profile-show-member-since-checkbox" type="checkbox"> + <span>Member since</span> + </label> + </div> + </div> + {# <div class="row"> <div class="col s3"> <p> <label> @@ -81,7 +81,7 @@ </label> </p> </div> - </div> + </div> #} <p></p> <br> {{ wtf.render_field(edit_profile_form.full_name, material_icon='badge') }} @@ -125,7 +125,33 @@ <ul class="collapsible no-autoinit settings-collapsible"> <li> <div class="collapsible-header" style="justify-content: space-between;"> - <span>Notification Settings</span> + <span>Account</span> + <i class="caret material-icons right">keyboard_arrow_right</i> + </div> + <div class="collapsible-body"> + <form method="POST" enctype="multipart/form-data"> + {{ edit_account_form.hidden_tag() }} + {{ wtf.render_field(edit_account_form.username, material_icon='person') }} + {{ wtf.render_field(edit_account_form.email, material_icon='email') }} + <div class="right-align"> + {{ wtf.render_field(edit_account_form.submit, material_icon='send') }} + </div> + </form> + <br> + <div class="divider"></div> + <p>Deleting an account has the following effects:</p> + <ul> + <li>All data associated with your corpora and jobs will be permanently deleted.</li> + <li>All settings will be permanently deleted.</li> + </ul> + <div class="right-align"> + <a class="btn red waves-effect waves-light modal-trigger" href="#delete-user"><i class="material-icons left">delete</i>Delete</a> + </div> + </div> + </li> + <li> + <div class="collapsible-header" style="justify-content: space-between;"> + <span>Notifications</span> <i class="caret material-icons">keyboard_arrow_right</i> </div> <div class="collapsible-body"> @@ -155,22 +181,6 @@ </form> </div> </li> - <li> - <div class="collapsible-header" style="justify-content: space-between;"> - <span>Delete Account</span> - <i class="caret material-icons right">keyboard_arrow_right</i> - </div> - <div class="collapsible-body"> - <p>Deleting an account has the following effects:</p> - <ul> - <li>All data associated with your corpora and jobs will be permanently deleted.</li> - <li>All settings will be permanently deleted.</li> - </ul> - <div class="right-align"> - <a class="btn red waves-effect waves-light modal-trigger" href="#delete-user"><i class="material-icons left">delete</i>Delete</a> - </div> - </div> - </li> </ul> </div> </div> -- GitLab