[chronojump-server] Added a user_detail page
- From: Max Ros i Morejon <maxros src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump-server] Added a user_detail page
- Date: Thu, 11 Jul 2019 14:22:41 +0000 (UTC)
commit 5195f6b4b2b4b05f8ac4c47d132522250087f965
Author: Max Ros i Morejon <mros33 gmail com>
Date: Thu Jul 11 16:22:26 2019 +0200
Added a user_detail page
.../organizations/api/serializers.py | 5 +
.../chronojump_networks/organizations/api/urls.py | 5 +
.../chronojump_networks/organizations/api/views.py | 20 ++-
.../chronojump_networks/organizations/urls.py | 5 +
.../chronojump_networks/organizations/views.py | 21 ++-
.../chronojump_networks/templates/layout.html | 2 +-
.../chronojump_networks/templates/pages/index.html | 2 +-
.../templates/users/user_detail.html | 145 +++++++++++++++++++++
.../templates/users/user_list.html | 0
9 files changed, 197 insertions(+), 8 deletions(-)
---
diff --git a/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
b/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
index 81d57b5..256fd09 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/api/serializers.py
@@ -9,6 +9,11 @@ class UserSerializer(serializers.ModelSerializer):
model = User
fields = [ 'id', 'name']
+class UserAllSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = User
+ fields = [ 'id', 'email', 'firstname', 'secondname', 'language' ]
+
class GymTableSerializer(serializers.ModelSerializer):
responsible = UserSerializer(many=False)
class Meta:
diff --git a/chronojumpserver-django/chronojump_networks/organizations/api/urls.py
b/chronojumpserver-django/chronojump_networks/organizations/api/urls.py
index 4555e7e..5f38830 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/api/urls.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/api/urls.py
@@ -66,6 +66,11 @@ urlpatterns = [
view=views.PlayerGroupsListView.as_view(),
name='player_groups'
),
+ url(
+ regex=r'^(?P<organization_id>\d+)/users/(?P<user_id>\d+)$',
+ view=views.UserUpdateView.as_view(),
+ name='update_user'
+ ),
url(
regex=r'^register_rfid/$',
view=views.register_rfid,
diff --git a/chronojumpserver-django/chronojump_networks/organizations/api/views.py
b/chronojumpserver-django/chronojump_networks/organizations/api/views.py
index abdcf7a..c5909f1 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/api/views.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/api/views.py
@@ -2,7 +2,7 @@ import os
import subprocess
from ..models import Player, GroupPlayer, Group, Station, Gym, Exercise, RFIDHistory, OrganizationStaff, User
from ..decorators import check_user_organization
-from .serializers import PlayerSerializer, StationSerializer, ExerciseSerializer, GymStationsSerializer,
GroupSerializer, GroupTableSerializer, UserSerializer, GymTableSerializer
+from .serializers import PlayerSerializer, StationSerializer, ExerciseSerializer, GymStationsSerializer,
GroupSerializer, GroupTableSerializer, UserSerializer, UserAllSerializer, GymTableSerializer
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
@@ -11,7 +11,7 @@ from django.conf import settings
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from rest_framework.response import Response
-from rest_framework.generics import GenericAPIView, ListAPIView, ListCreateAPIView, DestroyAPIView,
RetrieveUpdateDestroyAPIView
+from rest_framework.generics import GenericAPIView, ListAPIView, ListCreateAPIView, DestroyAPIView,
RetrieveUpdateDestroyAPIView, RetrieveAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin
from rest_framework.permissions import IsAuthenticated
@@ -301,6 +301,22 @@ class PlayerGroupsListView(ListCreateAPIView):
resp_n = [r.name for r in resp]
setattr(group, 'responsible_name', resp_n[0])
return groups
+
+class UserUpdateView(RetrieveAPIView):
+ permission_classes = (IsAuthenticated, )
+ serializer_class = UserAllSerializer
+ queryset = ''
+
+ def put(self, request, *args, **kwars):
+ print "Update user"
+ data = dict(request.data)
+ o = User.objects.get(id=int(data['id'][0]))
+ o.first_name = str(data['firstname'][0].encode('utf-8'))
+ o.last_name = str(data['secondname'][0].encode('utf-8'))
+ o.email = str(data['email'][0].encode('utf-8'))
+ o.language = str(data['language'][0])
+ o.save()
+ return JsonResponse({}, status=200, safe=False)
def register_rfid(request):
"""Call an external program to read rfid and return the value read."""
diff --git a/chronojumpserver-django/chronojump_networks/organizations/urls.py
b/chronojumpserver-django/chronojump_networks/organizations/urls.py
index be97359..634d947 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/urls.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/urls.py
@@ -53,6 +53,11 @@ urlpatterns = [
view=views.GymDetailTemplateView.as_view(),
name='gym_detail'
),
+ url(
+ regex=r'^(?P<organization_id>\d+)/users/(?P<user_id>\d+)$',
+ view=views.UserDetailTemplateView.as_view(),
+ name='user_page'
+ ),
url(
regex=r'^login$',
view=views.organization_login,
diff --git a/chronojumpserver-django/chronojump_networks/organizations/views.py
b/chronojumpserver-django/chronojump_networks/organizations/views.py
index 088e1cf..fd67171 100644
--- a/chronojumpserver-django/chronojump_networks/organizations/views.py
+++ b/chronojumpserver-django/chronojump_networks/organizations/views.py
@@ -10,7 +10,7 @@ from django.views.generic import DetailView, ListView, RedirectView, UpdateView,
from django.utils.translation import ugettext_lazy as _
from django.utils import translation
-from .models import Organization, Station, Group, Gym, Player
+from .models import Organization, Station, Group, Gym, Player, User
from .forms import UserLoginForm
from .decorators import check_user_organization
@@ -51,7 +51,7 @@ class GymDetailTemplateView(LoginRequiredMixin, TemplateView):
template_name = 'organizations/gyms/gym_detail.html'
def get_context_data(self, **kwargs):
- """Pass to the template the Group object"""
+ """Pass to the template the Gym object"""
context = super(GymDetailTemplateView,self).get_context_data(**kwargs)
gym_id = int(kwargs['gym_id'])
@@ -64,14 +64,27 @@ class PlayerListTemplateView(LoginRequiredMixin, TemplateView):
template_name = 'organizations/players/players_list.html'
class GroupListTemplateView(LoginRequiredMixin, TemplateView):
- """ Show the Player List
+ """ Show the Group List
"""
template_name = 'organizations/groups/groups_list.html'
class GymListTemplateView(LoginRequiredMixin, TemplateView):
- """ Show the Player List
+ """ Show the Gym List
"""
template_name = 'organizations/gyms/gyms_list.html'
+
+class UserDetailTemplateView(LoginRequiredMixin, TemplateView):
+ """ Show the User details
+ """
+ template_name = 'users/user_detail.html'
+
+ def get_context_data(self, **kwargs):
+ """Pass to the template the User object"""
+
+ context = super(UserDetailTemplateView,self).get_context_data(**kwargs)
+ user_id = int(kwargs['user_id'])
+ context['user'] = User.objects.get(id=user_id)
+ return context
#
# Login methods and views
diff --git a/chronojumpserver-django/chronojump_networks/templates/layout.html
b/chronojumpserver-django/chronojump_networks/templates/layout.html
index 81f4584..3d32f6a 100644
--- a/chronojumpserver-django/chronojump_networks/templates/layout.html
+++ b/chronojumpserver-django/chronojump_networks/templates/layout.html
@@ -56,7 +56,7 @@
{% endif %}
</ul>
<ul class="navbar-nav justify-content-end">
- <li class="nav-item active"><a class="nav-link">{% trans 'Hello, '%}{{user.name}}</a></li>
+ <li class="nav-item active"><a class="nav-link" href="{% url 'organizations:user_page'
organization_id=user.organization.id user_id=user.id %}">{% trans 'Hello, '%}{{user.name}}</a></li>
<li class="nav-item active"><a class="nav-link" href="{% url 'logout' %}">{% trans 'Close session'
%}</a></li>
</ul>
</div>
diff --git a/chronojumpserver-django/chronojump_networks/templates/pages/index.html
b/chronojumpserver-django/chronojump_networks/templates/pages/index.html
index a13328d..254feb0 100644
--- a/chronojumpserver-django/chronojump_networks/templates/pages/index.html
+++ b/chronojumpserver-django/chronojump_networks/templates/pages/index.html
@@ -30,7 +30,7 @@
<div class="col-md-6">
<div class="float-right">
<ul class="nav">
- <li class="nav-item active"><a class="nav-link text-white">{% trans 'Welcome,
'%}{{user.name}}</a></li>
+ <li class="nav-item active"><a href="{% url 'organizations:user_page'
organization_id=user.organization.id user_id=user.id %}" class="nav-link text-white">{% trans 'Welcome,
'%}{{user.name}}</a></li>
<li class="nav-item active"><a href="{% url 'logout' %}" class="nav-link text-white">{% trans
'Close session' %}</a></li>
</ul>
</div>
diff --git a/chronojumpserver-django/chronojump_networks/templates/users/user_detail.html
b/chronojumpserver-django/chronojump_networks/templates/users/user_detail.html
new file mode 100644
index 0000000..6afc70b
--- /dev/null
+++ b/chronojumpserver-django/chronojump_networks/templates/users/user_detail.html
@@ -0,0 +1,145 @@
+{% extends 'layout.html' %}
+{% load static i18n %}
+
+{% block title %}Chronojump Networks | {{user.organization.name}} | {{group.name}}{% endblock %}
+
+{% block css %}
+{{ block.super }}
+<link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap4.min.css">
+<link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.5.1/css/buttons.bootstrap4.min.css">
+<!--<link rel="stylesheet"
href="https://cdn.datatables.net/fixedcolumns/3.2.4/css/fixedColumns.bootstrap4.min.css">-->
+
+{% endblock %}
+
+{% block content %}
+{% csrf_token %}
+
+<div class="page-header row">
+ <div class="col-sm-8">
+ {% if user.organization.image %}
+ <img src="{{MEDIA_URL}}{{ user.organization.image }}" class="img-fluid float-left" width="48px"
height="48px" style="margin-top:12px;margin-right:10px;" />
+ {% else %}
+ <img src="{% static 'images/logo_club.png' %}" class="img-fluid float-left" width="48px"
height="48px" style="margin-top:12px;margin-right:10px;" />
+ {% endif %}
+ <h1 class="display-4">{{user.name}} </h1>
+ <h1 class="display-4"> <small class="text-muted" style="font-size:32px">{% trans 'Details'
%}</small></h1>
+ </div>
+ <div class="col-sm-4">
+ <dl class="row" style="margin-top:10px">
+ <dt class="col-sm-4 text-right">{% trans 'Organization' %}:</dt>
+ <dd class="col-sm-8">{{ user.organization.name }}</dd>
+ </dl>
+ <dl class="row" style="margin-top:10px">
+ <dt class="col-sm-4 text-right">{% trans 'Username' %}:</dt>
+ <dd class="col-sm-8">{{ user.username }}</dd>
+ </dl>
+ <!--<div class="row" style="margin-top:10px">
+ <div class="col" style="margin-left:50px">
+ <button id="btnPas" type="button" class="btn btn-outline-secondary">{% trans 'Change password'
%}</button>
+ </div>
+ </div>-->
+ </div>
+</div>
+
+<div class="container">
+ <div class="row" style="margin-bottom:20px">
+ <div class="col-sm-12">
+ <label for="email">{% trans 'Email' %}</label>
+ <input name="email" class="form-control" id="email" type="text" value="{{user.email}}">
+ </div>
+ </div>
+ <div class="row" style="margin-bottom:20px">
+ <div class="col-sm-6">
+ <label for="firstname">{% trans 'First name' %}</label>
+ <input name="firstname" class="form-control" id="firstname" type="text" value="{{user.first_name}}">
+ </div>
+ <div class="col-sm-6">
+ <label for="secondname">{% trans 'Second name' %}</label>
+ <input name="secondname" class="form-control" id="secondname" type="text" value="{{user.last_name}}">
+ </div>
+ </div>
+ <div class="row" style="margin-bottom:20px">
+ <div class="col-sm-4">
+ <label for="language">{% trans 'Language' %}</label>
+ <select name="language" class="form-control" id="language">
+ <option value="en">{% trans 'English' %}</option>
+ <option value="es">{% trans 'Spanish' %}</option>
+ <option value="fr">{% trans 'French' %}</option>
+ <option value="ca">{% trans 'Catalan' %}</option>
+ </select>
+ </div>
+ <div class="col-sm-4">
+ <label for="isstaff">{% trans 'Staff' %}</label>
+ <input name="isstaff" class="form-control" id="isstaff" type="text" value="{{user.is_staff}}"
disabled readonly>
+ </div>
+ <div class="col-sm-4">
+ <button id="btnSave" type="button" class="btn btn-outline-primary"
style="bottom:0;left:0;position:absolute;">{% trans 'Save changes' %}</button>
+ </div>
+ </div>
+</div>
+
+{% endblock %}
+
+{% block javascript %}
+{{ block.super }}
+<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
+<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js"></script>
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.bootstrap4.min.js"></script>
+<script src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.html5.min.js"></script>
+
+<script>
+ var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
+ var lgc = false;
+
+ $(document).ready(function() {
+ var lg = "{{user.language}}";
+ $('#language').val(lg);
+
+ $('#btnSave').on('click', function(e) {
+ e.preventDefault();
+ var user = serializeUser();
+ $.ajax({
+ 'url': "{% url 'api_organizations:update_user' organization_id=user.organization.id
user_id=user.id %}",
+ 'method': 'PUT',
+ 'data': user,
+ success: function(data) {
+ if(lgc) {
+ alert("{% trans 'The user has been updated. You will have to re-login in order to
see the language changed.' %}");
+ } else {
+ alert("{% trans 'The user has been updated' %}");
+ }
+ },
+ error: function(request, status, error) {
+ alert(request.responseText);
+ }
+
+ });
+ });
+
+ $('#language').on('change', function() {
+ lgc = true;
+ });
+
+ /* Get all the values in the form into json object */
+ function serializeUser() {
+ let id = {{user.id}};
+ let email = $('#email').val();
+ let firstname = $('#firstname').val();
+ let secondname = $('#secondname').val();
+ let language = $('#language').val();
+ var user = {
+ 'id': id,
+ 'email': email,
+ 'firstname': firstname,
+ 'secondname' : secondname,
+ 'language': language
+ }
+ console.log(user);
+ return user;
+ }
+
+ });
+</script>
+
+{% endblock %}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]