Allow users to select the locale and timezone in their profile.
parent
bd155f9145
commit
49faaf7e8c
|
@ -19,6 +19,7 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import BooleanField
|
||||
from wtforms import PasswordField
|
||||
from wtforms import SelectField
|
||||
from wtforms import StringField
|
||||
from wtforms import SubmitField
|
||||
from wtforms import TextAreaField
|
||||
|
@ -27,6 +28,8 @@ from wtforms import validators
|
|||
from wtforms_sqlalchemy.fields import QuerySelectMultipleField
|
||||
|
||||
from cupola.forms.projects import ProjectUsersFormBase
|
||||
from cupola.forms.utils import LANGUAGES_CHOICE
|
||||
from cupola.forms.utils import TIMEZONE_CHOICE
|
||||
from cupola.models.users import role_query_factory
|
||||
|
||||
|
||||
|
@ -38,6 +41,10 @@ class ProfileForm(FlaskForm):
|
|||
bio = TextAreaField("Biography")
|
||||
notification_type = ProjectUsersFormBase.notification_type
|
||||
notification_limit = ProjectUsersFormBase.notification_limit
|
||||
|
||||
locale = SelectField("Locale", choices=LANGUAGES_CHOICE)
|
||||
timezone = SelectField("Timezone", choices=TIMEZONE_CHOICE)
|
||||
|
||||
submit = SubmitField("Save")
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# coding=utf8
|
||||
#
|
||||
# utils.py: Form utilities
|
||||
# Copyright (C) 2016 Sam Black <samwwwblack@lapwing.org>
|
||||
# Copyright (C) 2016-2017 Sam Black <samwwwblack@lapwing.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -16,7 +16,19 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from pytz import common_timezones
|
||||
from sqlalchemy_utils.types.choice import Choice
|
||||
from cupola.utils import LANGUAGES
|
||||
|
||||
LANGUAGES_CHOICE = tuple((short, description)
|
||||
for short, description in LANGUAGES.items())
|
||||
|
||||
|
||||
def _timezone_choice():
|
||||
tzs = [("UTC", "UTC")]
|
||||
tzs.extend([(tz, tz) for tz in common_timezones if tz != "UTC"])
|
||||
return tuple(tzs)
|
||||
TIMEZONE_CHOICE = _timezone_choice()
|
||||
|
||||
|
||||
# This is from WTForms-Alchemy
|
||||
|
|
|
@ -77,7 +77,7 @@ class User(db.Model, UserMixin):
|
|||
notification_limit = db.Column(db.Integer(), default=20)
|
||||
|
||||
locale = db.Column(LocaleType())
|
||||
timezone = db.Column(TimezoneType())
|
||||
timezone = db.Column(TimezoneType(backend="pytz"))
|
||||
|
||||
@property
|
||||
def username(self):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
rotate.js: Rotate buttons when clicked.
|
||||
cupola.js: Generic JS for all of Cupola.
|
||||
Copyright (C) 2017 Sam Black <samwwwblack@lapwing.org>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -15,6 +15,10 @@
|
|||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
$(".rotatable").click(function(){
|
||||
$(this).toggleClass("right");
|
||||
$(document).ready(function() {
|
||||
$('.combobox').combobox();
|
||||
|
||||
$(".rotatable").click(function(){
|
||||
$(this).toggleClass("right");
|
||||
});
|
||||
});
|
|
@ -27,7 +27,8 @@
|
|||
<script src="/static/js/patternfly/dataTables.colVis-1.1.2.js" type="text/javascript"></script>
|
||||
<script src="/static/js/patternfly/dataTables.colReorder-1.4.1.js" type="text/javascript"></script>
|
||||
<script src="/static/js/patternfly/patternfly-3.28.3.js" type="text/javascript"></script>
|
||||
<script src="/static/js/rotate.js" type="text/javascript"></script>
|
||||
<script src="/static/js/patternfly/bootstrap-combobox-1.1.8.js" type="text/javascript"></script>
|
||||
<script src="/static/js/cupola.js" type="text/javascript"></script>
|
||||
{% block body_js -%}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{% macro _render_field_data(field, field_block_id, field_text,
|
||||
field_block_status, static=False, add_hidden=False) %}
|
||||
{% set class = ["is_invalid" if kwargs.get("error"),
|
||||
field.render_kw.get("class", "") if field.render_kw,
|
||||
kwargs.get("class_", ""),
|
||||
"form-control"] %}
|
||||
{% if static or field.flags.static %}
|
||||
{% if add_hidden or field.flags.add_hidden %}
|
||||
<input type="hidden" name="{{ field.name }}" id="{{ field_block_id }}" value="{{ field.data }}">
|
||||
|
@ -8,7 +12,7 @@
|
|||
{{ field.data or "No information" }}
|
||||
</p>
|
||||
{% else %}
|
||||
{{ field(class="form-control", id=field_block_id, placeholder=field_text,
|
||||
{{ field(class=class|join(" ")|trim, id=field_block_id, placeholder=field_text,
|
||||
aria_describedby=field_block_status, readonly=field.flags.readonly, **kwargs) | safe }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
{{ render_field(form.fullname) }}
|
||||
{{ render_field(form.bio) }}
|
||||
</div>
|
||||
<div class="col-lg-12">
|
||||
<h4 class="col-lg-offset-1">Localisation</h4>
|
||||
{{ render_field(form.locale) }}
|
||||
{{ render_field(form.timezone, class_="combobox") }}
|
||||
</div>
|
||||
<div class="col-lg-12">
|
||||
<h4 class="col-lg-offset-1">Project Event Notifications</h4>
|
||||
{{ render_field(form.notification_type) }}
|
||||
|
|
|
@ -121,10 +121,11 @@ def profile(user_id):
|
|||
:rtype: jinja2.Template
|
||||
"""
|
||||
user = User.query.get_or_404(user_id)
|
||||
user_form = ProfileForm(request.form, obj=user)
|
||||
user_form = ProfileForm(obj=user)
|
||||
|
||||
if user_form.validate_on_submit():
|
||||
user_form.populate_obj(user)
|
||||
db.session.commit()
|
||||
flash(gettext("Profile updated successfully"), "success")
|
||||
return redirect(url_for("users.profile", user_id=user.id))
|
||||
return render_template("users/profile.html", user=user, form=user_form)
|
||||
|
|
|
@ -16,3 +16,4 @@ raven
|
|||
arrow
|
||||
sqlalchemy-utils
|
||||
Flask-BabelEx
|
||||
pytz
|
||||
|
|
Loading…
Reference in New Issue