From 3c6d5756c57976882041cab912b5ab475cfd2a6d Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 14 May 2019 13:21:20 +1000 Subject: [PATCH 1/4] Create a simple user settings view --- InvenTree/InvenTree/urls.py | 4 +++- InvenTree/InvenTree/views.py | 7 +++++++ InvenTree/templates/InvenTree/settings.html | 21 +++++++++++++++++++++ InvenTree/templates/navbar.html | 2 ++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 InvenTree/templates/InvenTree/settings.html diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index fe8a624458..572225864f 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -30,7 +30,7 @@ from django.conf.urls.static import static from django.views.generic.base import RedirectView from rest_framework.documentation import include_docs_urls -from .views import IndexView, SearchView +from .views import IndexView, SearchView, SettingsView from users.urls import user_urls @@ -61,6 +61,8 @@ urlpatterns = [ url(r'^login/', auth_views.LoginView.as_view(), name='login'), url(r'^logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='logout'), + + url(r'^settings/', SettingsView.as_view(), name='settings'), url(r'^admin/', admin.site.urls, name='inventree-admin'), diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 08ca9e0eb5..aea938f961 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -414,3 +414,10 @@ class SearchView(TemplateView): context['query'] = query return super(TemplateView, self).render_to_response(context) + + +class SettingsView(TemplateView): + """ View for configuring User settings + """ + + template_name = "InvenTree/settings.html" diff --git a/InvenTree/templates/InvenTree/settings.html b/InvenTree/templates/InvenTree/settings.html new file mode 100644 index 0000000000..99aa03ccb1 --- /dev/null +++ b/InvenTree/templates/InvenTree/settings.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} + +{% block page_title %} +InvenTree | Settings +{% endblock %} + +{% block content %} +

Settings

+
+ +Logged in as {{ user.username }} + +{% endblock %} + +{% block js_load %} +{{ block.super }} +{% endblock %} + +{% block js_ready %} +{{ block.super }} +{% endblock %} \ No newline at end of file diff --git a/InvenTree/templates/navbar.html b/InvenTree/templates/navbar.html index 53a7bb4894..5cb71d13ac 100644 --- a/InvenTree/templates/navbar.html +++ b/InvenTree/templates/navbar.html @@ -19,7 +19,9 @@ {% if user.is_authenticated %} {% if user.is_staff %}
  • Admin
  • +
    {% endif %} +
  • Settings
  • Logout
  • {% else %}
  • Login
  • From 0032ea3409e3f113b35ea1274a5b1d9ed899e430 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 14 May 2019 13:33:47 +1000 Subject: [PATCH 2/4] Add a form to edit basic user settings - First / last name - Email address --- InvenTree/InvenTree/forms.py | 15 +++++++- InvenTree/InvenTree/urls.py | 4 ++- InvenTree/InvenTree/views.py | 14 +++++++- InvenTree/templates/InvenTree/settings.html | 40 +++++++++++++++++++-- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 7ec4401101..901ef0b26a 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from django import forms from crispy_forms.helper import FormHelper - +from django.contrib.auth.models import User class HelperForm(forms.ModelForm): """ Provides simple integration of crispy_forms extension. """ @@ -33,3 +33,16 @@ class DeleteForm(forms.Form): fields = [ 'confirm_delete' ] + + +class EditUserForm(HelperForm): + """ Form for editing user information + """ + + class Meta: + model = User + fields = [ + 'first_name', + 'last_name', + 'email' + ] \ No newline at end of file diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 572225864f..0e24fddd47 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -30,7 +30,7 @@ from django.conf.urls.static import static from django.views.generic.base import RedirectView from rest_framework.documentation import include_docs_urls -from .views import IndexView, SearchView, SettingsView +from .views import IndexView, SearchView, SettingsView, EditUserView from users.urls import user_urls @@ -64,6 +64,8 @@ urlpatterns = [ url(r'^settings/', SettingsView.as_view(), name='settings'), + url(r'^edit-user/', EditUserView.as_view(), name='edit-user'), + url(r'^admin/', admin.site.urls, name='inventree-admin'), url(r'^qr_code/', include(qr_code_urls, namespace='qr_code')), diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index aea938f961..5b889246f6 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -17,7 +17,7 @@ from django.views.generic.base import TemplateView from part.models import Part -from .forms import DeleteForm +from .forms import DeleteForm, EditUserForm from .helpers import str2bool from rest_framework import views @@ -371,6 +371,18 @@ class AjaxDeleteView(AjaxMixin, UpdateView): return self.renderJsonResponse(request, form, data=data, context=context) +class EditUserView(AjaxUpdateView): + """ View for editing user information """ + + ajax_template_name = "modal_form.html" + ajax_form_title = "Edit User Information" + form_class = EditUserForm + + def get_object(self): + return self.request.user + + + class IndexView(TemplateView): """ View for InvenTree index page """ diff --git a/InvenTree/templates/InvenTree/settings.html b/InvenTree/templates/InvenTree/settings.html index 99aa03ccb1..56a8b1f0c2 100644 --- a/InvenTree/templates/InvenTree/settings.html +++ b/InvenTree/templates/InvenTree/settings.html @@ -5,10 +5,36 @@ InvenTree | Settings {% endblock %} {% block content %} -

    Settings

    +

    InvenTree Settings


    -Logged in as {{ user.username }} +
    +
    +

    User Information

    +
    +
    +
    +
    Edit
    +
    Set Password
    +
    +
    +
    + + + + + + + + + + + + + + + +
    First Name{{ user.first_name }}
    Last Name{{ user.last_name }}
    Email Address{{ user.email }}
    {% endblock %} @@ -18,4 +44,14 @@ Logged in as {{ user.username }} {% block js_ready %} {{ block.super }} + + $("#edit-user").on('click', function() { + launchModalForm( + "{% url 'edit-user' %}", + { + reload: true, + } + ); + }); + {% endblock %} \ No newline at end of file From b996c03f618303845755fa6ce813493da5e633df Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 14 May 2019 13:58:23 +1000 Subject: [PATCH 3/4] Add a 'set password' form --- InvenTree/InvenTree/forms.py | 28 +++++++++++++- InvenTree/InvenTree/urls.py | 3 +- InvenTree/InvenTree/views.py | 43 ++++++++++++++++++++- InvenTree/templates/InvenTree/password.html | 7 ++++ InvenTree/templates/InvenTree/settings.html | 9 +++++ 5 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 InvenTree/templates/InvenTree/password.html diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 901ef0b26a..f528c5c110 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -45,4 +45,30 @@ class EditUserForm(HelperForm): 'first_name', 'last_name', 'email' - ] \ No newline at end of file + ] + + +class SetPasswordForm(HelperForm): + """ Form for setting user password + """ + + enter_password = forms.CharField(max_length=100, + min_length=8, + required=True, + initial='', + widget=forms.PasswordInput(attrs={'autocomplete': 'off'}), + help_text='Enter new password') + + confirm_password = forms.CharField(max_length=100, + min_length=8, + required=True, + initial='', + widget=forms.PasswordInput(attrs={'autocomplete': 'off'}), + help_text='Confirm new password') + + class Meta: + model = User + fields = [ + 'enter_password', + 'confirm_password' + ] diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 0e24fddd47..2872096c08 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -30,7 +30,7 @@ from django.conf.urls.static import static from django.views.generic.base import RedirectView from rest_framework.documentation import include_docs_urls -from .views import IndexView, SearchView, SettingsView, EditUserView +from .views import IndexView, SearchView, SettingsView, EditUserView, SetPasswordView from users.urls import user_urls @@ -65,6 +65,7 @@ urlpatterns = [ url(r'^settings/', SettingsView.as_view(), name='settings'), url(r'^edit-user/', EditUserView.as_view(), name='edit-user'), + url(r'^set-password/', SetPasswordView.as_view(), name='set-password'), url(r'^admin/', admin.site.urls, name='inventree-admin'), diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 5b889246f6..041603f7fb 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -17,7 +17,7 @@ from django.views.generic.base import TemplateView from part.models import Part -from .forms import DeleteForm, EditUserForm +from .forms import DeleteForm, EditUserForm, SetPasswordForm from .helpers import str2bool from rest_framework import views @@ -382,6 +382,47 @@ class EditUserView(AjaxUpdateView): return self.request.user +class SetPasswordView(AjaxUpdateView): + """ View for setting user password """ + + ajax_template_name = "InvenTree/password.html" + ajax_form_title = "Set Password" + form_class = SetPasswordForm + + def get_object(self): + return self.request.user + + def post(self, request, *args, **kwargs): + + form = self.get_form() + + valid = form.is_valid() + + p1 = request.POST.get('enter_password', '') + p2 = request.POST.get('confirm_password', '') + + if valid: + # Passwords must match + + if not p1 == p2: + error = 'Password fields must match' + form.errors['enter_password'] = [error] + form.errors['confirm_password'] = [error] + + valid = False + + data = { + 'form_valid': valid + } + + if valid: + user = self.request.user + + user.set_password(p1) + user.save() + + return self.renderJsonResponse(request, form, data=data) + class IndexView(TemplateView): """ View for InvenTree index page """ diff --git a/InvenTree/templates/InvenTree/password.html b/InvenTree/templates/InvenTree/password.html new file mode 100644 index 0000000000..d109a09a7a --- /dev/null +++ b/InvenTree/templates/InvenTree/password.html @@ -0,0 +1,7 @@ +{% extends "modal_form.html" %} + +{% block pre_form_content %} + +{{ block.super }} + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/templates/InvenTree/settings.html b/InvenTree/templates/InvenTree/settings.html index 56a8b1f0c2..2a2bbcc144 100644 --- a/InvenTree/templates/InvenTree/settings.html +++ b/InvenTree/templates/InvenTree/settings.html @@ -54,4 +54,13 @@ InvenTree | Settings ); }); + $("#edit-password").on('click', function() { + launchModalForm( + "{% url 'set-password' %}", + { + reload: true, + } + ); + }); + {% endblock %} \ No newline at end of file From ba1e24cce8c73ee0030c31bf60499431b663f461 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 14 May 2019 13:59:10 +1000 Subject: [PATCH 4/4] PEP --- InvenTree/InvenTree/forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index f528c5c110..c186ff8589 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -9,6 +9,7 @@ from django import forms from crispy_forms.helper import FormHelper from django.contrib.auth.models import User + class HelperForm(forms.ModelForm): """ Provides simple integration of crispy_forms extension. """ @@ -49,7 +50,7 @@ class EditUserForm(HelperForm): class SetPasswordForm(HelperForm): - """ Form for setting user password + """ Form for setting user password """ enter_password = forms.CharField(max_length=100,