Commit 126195a826e8130a3e65c01294f8223d1933959d

Authored by Felipe Henrique de Almeida Bormann
2 parents 45faf53b 6e6c6465

Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring

amadeus/templates/base.html
@@ -107,10 +107,8 @@ @@ -107,10 +107,8 @@
107 <li title data-original-title="{% trans 'settings' %}"> 107 <li title data-original-title="{% trans 'settings' %}">
108 <a href="" data-toggle="dropdown"><i class="fa fa-cog" aria-hidden="true"></i></a> 108 <a href="" data-toggle="dropdown"><i class="fa fa-cog" aria-hidden="true"></i></a>
109 <ul class="dropdown-menu pull-right"> 109 <ul class="dropdown-menu pull-right">
110 - <li><a href="#">{% trans 'Perfil' %}</a></li>  
111 - <li><a href="#">{% trans 'Edit Profile' %}</a></li>  
112 - <li><a href="#">{% trans 'Change password' %}</a></li>  
113 - <li><a href="#">{% trans 'Remove account' %}</a></li> 110 + <li><a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>
  111 + <li><a href="#">{% trans 'Manage Courses' %}</a></li>
114 </ul> 112 </ul>
115 </li> 113 </li>
116 <li> 114 <li>
@@ -171,6 +169,11 @@ @@ -171,6 +169,11 @@
171 169
172 <!-- Init material Bootstrap --> 170 <!-- Init material Bootstrap -->
173 <script type="text/javascript">$.material.init()</script> 171 <script type="text/javascript">$.material.init()</script>
  172 + <script type="text/javascript">
  173 + $('.text_wysiwyg').summernote({
  174 + height: 200
  175 + });
  176 + </script>
174 </body> 177 </body>
175 178
176 </html> 179 </html>
177 \ No newline at end of file 180 \ No newline at end of file
amadeus/templates/pagination.html 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<div class="row-fluid">
  2 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  3 + <ul class="pagination">
  4 + {% for page_number in paginator.page_range %}
  5 + <li{% if page_obj.number == page_number %} class="active"{% endif %}>
  6 + <a href="?page={{ page_number }}{{ getvars }}">{{ page_number }}</a>
  7 + </li>
  8 + {% endfor %}
  9 + </ul>
  10 + </div>
  11 +</div>
0 \ No newline at end of file 12 \ No newline at end of file
amadeus/templatetags/__init__.py 0 → 100644
amadeus/templatetags/pagination.py 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +from django import template
  2 +
  3 +register = template.Library()
  4 +
  5 +@register.inclusion_tag('pagination.html')
  6 +def pagination(request, paginator, page_obj):
  7 + context = {
  8 + 'request': request,
  9 + 'paginator': paginator,
  10 + 'page_obj': page_obj,
  11 + }
  12 +
  13 + getvars = request.GET.copy()
  14 +
  15 + if 'page' in getvars:
  16 + del getvars['page']
  17 +
  18 + if len(getvars) > 0:
  19 + context['getvars'] = '&%s' % getvars.urlencode()
  20 +
  21 + return context
0 \ No newline at end of file 22 \ No newline at end of file
users/forms.py
@@ -86,4 +86,40 @@ class ProfileForm(Validation): @@ -86,4 +86,40 @@ class ProfileForm(Validation):
86 fields = ['social_name', 'description', 'show_email', 'image'] 86 fields = ['social_name', 'description', 'show_email', 'image']
87 widgets = { 87 widgets = {
88 'description': forms.Textarea, 88 'description': forms.Textarea,
89 - }  
90 \ No newline at end of file 89 \ No newline at end of file
  90 + }
  91 +
  92 +class UserForm(Validation):
  93 + is_edit = False
  94 +
  95 + def __init__(self, *args, **kwargs):
  96 + is_update = kwargs.pop('is_edit', False)
  97 +
  98 + super(UserForm, self).__init__(*args, **kwargs)
  99 +
  100 + self.is_edit = is_update
  101 +
  102 + if self.is_edit:
  103 + del self.fields['password']
  104 + del self.fields['password2']
  105 +
  106 + if not is_edit:
  107 + password = forms.CharField(label=_('Password'), widget = forms.PasswordInput, required = False)
  108 + password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput, required = False)
  109 +
  110 +
  111 + def save(self, commit=True):
  112 + super(UserForm, self).save(commit=False)
  113 +
  114 + if not self.is_edit:
  115 + self.instance.set_password(self.cleaned_data['password'])
  116 +
  117 + self.instance.save()
  118 +
  119 + return self.instance
  120 +
  121 + class Meta:
  122 + model = User
  123 + fields = ['email', 'username', 'last_name', 'social_name', 'description', 'show_email', 'image', 'is_staff', 'is_active']
  124 + widgets = {
  125 + 'description': forms.Textarea,
  126 + }
91 \ No newline at end of file 127 \ No newline at end of file
users/migrations/0003_auto_20161222_1505.py 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-12-22 18:05
  3 +from __future__ import unicode_literals
  4 +
  5 +import django.core.validators
  6 +from django.db import migrations, models
  7 +import re
  8 +import users.models
  9 +
  10 +
  11 +class Migration(migrations.Migration):
  12 +
  13 + dependencies = [
  14 + ('users', '0002_auto_20161220_1700'),
  15 + ]
  16 +
  17 + operations = [
  18 + migrations.AlterField(
  19 + model_name='user',
  20 + name='email',
  21 + field=models.EmailField(help_text='Your email address that will be used to access the platform', max_length=254, unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[\\w.@+-]+$', 32), 'Type a valid email. This fields should only contain letters, numbers and the characteres: @/./+/-/_ .', 'invalid')], verbose_name='Mail'),
  22 + ),
  23 + migrations.AlterField(
  24 + model_name='user',
  25 + name='image',
  26 + field=models.ImageField(blank=True, null=True, upload_to='users/', validators=[users.models.validate_img_extension], verbose_name='Photo'),
  27 + ),
  28 + migrations.AlterField(
  29 + model_name='user',
  30 + name='show_email',
  31 + field=models.IntegerField(blank=True, choices=[(1, 'Allow everyone to see my address'), (2, 'Only classmates can see my address'), (3, 'Nobody can see my address')], default=1, null=True, verbose_name='Show email?'),
  32 + ),
  33 + ]
users/models.py
@@ -29,7 +29,7 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -29,7 +29,7 @@ class User(AbstractBaseUser, PermissionsMixin):
29 image = models.ImageField(verbose_name = _('Photo'), null=True, blank = True, upload_to = 'users/', validators = [validate_img_extension]) 29 image = models.ImageField(verbose_name = _('Photo'), null=True, blank = True, upload_to = 'users/', validators = [validate_img_extension])
30 date_created = models.DateTimeField(_('Create Date'), auto_now_add = True) 30 date_created = models.DateTimeField(_('Create Date'), auto_now_add = True)
31 last_update = models.DateTimeField(_('Last Update'), auto_now = True) 31 last_update = models.DateTimeField(_('Last Update'), auto_now = True)
32 - show_email = models.IntegerField(_('Show email?'), null = True, blank = True, choices = ((1, _('Allow everyone to see my address')), (2, _('Only classmates can see my address')), (3, _('Nobody can see my address')))) 32 + show_email = models.IntegerField(_('Show email?'), null = True, blank = True, choices = ((1, _('Allow everyone to see my address')), (2, _('Only classmates can see my address')), (3, _('Nobody can see my address'))), default = 1)
33 is_staff = models.BooleanField(_('Administrator'), default = False) 33 is_staff = models.BooleanField(_('Administrator'), default = False)
34 is_active = models.BooleanField(_('Active'), default = True) 34 is_active = models.BooleanField(_('Active'), default = True)
35 35
@@ -46,7 +46,7 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -46,7 +46,7 @@ class User(AbstractBaseUser, PermissionsMixin):
46 return self.social_name or self.username 46 return self.social_name or self.username
47 47
48 def get_short_name(self): 48 def get_short_name(self):
49 - return self.username 49 + return str(self)
50 50
51 @property 51 @property
52 def image_url(self): 52 def image_url(self):
users/templates/list_users.html
@@ -1,95 +0,0 @@ @@ -1,95 +0,0 @@
1 -{% extends 'home.html' %}  
2 -  
3 -{% load i18n pagination django_bootstrap_breadcrumbs permission_tags static %}  
4 -  
5 -{% block breadcrumbs %}  
6 -  
7 - {{ block.super }}  
8 - {% breadcrumb 'Manage Users' 'users:manage' %}  
9 -  
10 -{% endblock %}  
11 -  
12 -{% block menu %}  
13 -{% endblock %}  
14 -  
15 -{% block content %}  
16 - {% if messages %}  
17 - {% for message in messages %}  
18 - <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">  
19 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
20 - <span aria-hidden="true">&times;</span>  
21 - </button>  
22 - <p>{{ message }}</p>  
23 - </div>  
24 - {% endfor %}  
25 - {% endif %}  
26 - <form action="" method="GET" class="form-horizontal">  
27 - <div class="form-group">  
28 - <div class="col-md-11 col-sm-11 col-xs-11">  
29 - <input type="text" class="form-control" name="search" placeholder="{% trans 'Search...' %}" />  
30 - </div>  
31 - <div class="col-md-1 col-sm-1 col-xs-1">  
32 - <button type="submit" class="btn btn-fab btn-fab-mini">  
33 - <i class="material-icons">search</i>  
34 - </button>  
35 - </div>  
36 - </div>  
37 - </form>  
38 -  
39 - {% if users|length > 0 %}  
40 - {% for acc in users %}  
41 - <div class="row panel panel-default">  
42 - <div class="panel-body">  
43 - <div class="col-md-4">  
44 - {% if acc.image %}  
45 - <div style="background-image: url('{{ acc.image.url }}'); background-size: 100% 100%; background-repeat: no-repeat;" alt="photoUser" class="img-circle img-responsive img-list-user"></div>  
46 - {% else %}  
47 - {% if acc.gender == 'M' %}  
48 - <img src="{% static 'img/male_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user">  
49 - {% else %}  
50 - <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user">  
51 - {% endif %}  
52 - {% endif %}  
53 - </div>  
54 - <div class="col-md-8">  
55 - <p>{% trans 'Name' %}: {{ acc.name }}</p>  
56 - <p>{% trans 'Profile' %}: {{ acc.get_type_profile_display }}</p>  
57 - <p>{% trans 'Email' %}: {{ acc.email }}</p>  
58 - <p>{% trans 'Contact' %}: {{ acc.phone }}</p>  
59 - <div align="right">  
60 - <a href="{% url 'users:update' acc.username %}" class="btn btn-raised btn-success">{% trans 'Edit' %}</a>  
61 - <a href="javascript:void(0)" class="btn btn-default btn-raised btn-lg" data-toggle="modal" data-target="#DeleteModal{{ forloop.counter }}">{% trans 'Delete' %}</a>  
62 - </div>  
63 - </div>  
64 -  
65 -  
66 - <!-- Modal -->  
67 - <div class="modal fade" id="DeleteModal{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="DeleteModalLabel">  
68 - <div class="modal-dialog" role="document">  
69 - <div class="modal-content">  
70 - <div class="modal-header">  
71 - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>  
72 - <h4 class="modal-title" id="DeleteModalLabel">{% trans 'Confirm delete' %}</h4>  
73 - </div>  
74 - <div class="modal-body">  
75 - {% trans 'Are you sure you want to delete the user' %} <b>{{acc.name}}</b>?  
76 - </div>  
77 - <div class="modal-footer">  
78 - <a href="#" class="btn btn-raised btn-default" data-dismiss="modal">{% trans 'Cancel' %}</a>  
79 - <a href="{% url 'users:delete' acc.username %}" class="btn btn-raised btn-success" style="margin-top: 0">{% trans 'Delete' %}</a>  
80 - </div>  
81 - </div>  
82 - </div>  
83 - </div>  
84 - </div>  
85 - </div>  
86 - {% endfor %}  
87 - {% pagination request paginator page_obj %}  
88 - {% else %}  
89 - <div class="row">  
90 - <div class="col-md-12 col-sm-12 col-xs-12">  
91 - <p>{% trans 'No users found' %}</p>  
92 - </div>  
93 - </div>  
94 - {% endif %}  
95 -{% endblock %}  
users/templates/users/_form.html 0 → 100644
@@ -0,0 +1,62 @@ @@ -0,0 +1,62 @@
  1 +{% load static i18n %}
  2 +{% load widget_tweaks %}
  3 +
  4 +<form method="post" action="" enctype="multipart/form-data">
  5 + {% csrf_token %}
  6 + {% for field in form %}
  7 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  8 + {% if field.auto_id == 'id_image' %}
  9 + {% if field.field.required %}
  10 + <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>
  11 + {% else %}
  12 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  13 + {% endif %}
  14 + {% render_field field class='form-control' %}
  15 + <div class="input-group">
  16 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">
  17 + <span class="input-group-btn input-group-sm">
  18 + <button type="button" class="btn btn-fab btn-fab-mini">
  19 + <i class="material-icons">attach_file</i>
  20 + </button>
  21 + </span>
  22 + </div>
  23 + {% elif field.auto_id == 'id_description' %}
  24 + {% if field.field.required %}
  25 + <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>
  26 + {% else %}
  27 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  28 + {% endif %}
  29 + {% render_field field class='form-control text_wysiwyg' %}
  30 + {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %}
  31 + <div class="checkbox">
  32 + <label for="{{ field.auto_id }}">
  33 + {% render_field field %} {{field.label}}
  34 + </label>
  35 + </div>
  36 + {% else %}
  37 + {% if field.field.required %}
  38 + <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>
  39 + {% else %}
  40 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  41 + {% endif %}
  42 + {% render_field field class='form-control' %}
  43 + {% endif %}
  44 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  45 + {% if field.errors %}
  46 + <div class="alert alert-danger alert-dismissible" role="alert">
  47 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  48 + <span aria-hidden="true">&times;</span>
  49 + </button>
  50 + <ul>
  51 + {% for error in field.errors %}
  52 + <li>{{ error }}</li>
  53 + {% endfor %}
  54 + </ul>
  55 + </div>
  56 + {% endif %}
  57 + </div>
  58 + {% endfor %}
  59 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  60 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-primary" />
  61 + </div>
  62 +</form>
0 \ No newline at end of file 63 \ No newline at end of file
users/templates/users/create.html
1 -{% extends 'list_users.html' %}  
2 -  
3 -{% load static i18n %}  
4 -{% load widget_tweaks %} 1 +{% extends 'users/list.html' %}
5 2
6 {% load django_bootstrap_breadcrumbs %} 3 {% load django_bootstrap_breadcrumbs %}
7 4
8 {% block breadcrumbs %} 5 {% block breadcrumbs %}
9 -  
10 - {{ block.super }} 6 + {{ block.super }}
11 {% breadcrumb 'Add User' 'users:create' %} 7 {% breadcrumb 'Add User' 'users:create' %}
12 -  
13 {% endblock %} 8 {% endblock %}
14 9
15 -  
16 {% block content %} 10 {% block content %}
17 - {% if messages %}  
18 - {% for message in messages %}  
19 - <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">  
20 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
21 - <span aria-hidden="true">&times;</span>  
22 - </button>  
23 - <p>{{ message }}</p>  
24 - </div>  
25 - {% endfor %}  
26 - {% endif %}  
27 -  
28 <div class="card"> 11 <div class="card">
29 <div class="card-content"> 12 <div class="card-content">
30 <div class="card-body"> 13 <div class="card-body">
31 - <form method="post" action="" enctype="multipart/form-data">  
32 - {% csrf_token %}  
33 - {% for field in form %}  
34 - <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">  
35 - {% if field.auto_id == 'id_birth_date' %}  
36 - {% if field.field.required %}  
37 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
38 - {% else %}  
39 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
40 - {% endif %}  
41 -  
42 - {% render_field field class='form-control date-picker' %}  
43 - {% elif field.auto_id == 'id_image' %}  
44 - {% if field.field.required %}  
45 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
46 - {% else %}  
47 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
48 - {% endif %}  
49 - {% render_field field class='form-control' %}  
50 - <div class="input-group">  
51 - <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">  
52 - <span class="input-group-btn input-group-sm">  
53 - <button type="button" class="btn btn-fab btn-fab-mini">  
54 - <i class="material-icons">attach_file</i>  
55 - </button>  
56 - </span>  
57 - </div>  
58 -  
59 - {% elif field.auto_id == 'id_curriculum' %}  
60 - {% if field.field.required %}  
61 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
62 - {% else %}  
63 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
64 - {% endif %}  
65 - {% render_field field class='form-control' %}  
66 - <div class="input-group">  
67 - <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">  
68 - <span class="input-group-btn input-group-sm">  
69 - <button type="button" class="btn btn-fab btn-fab-mini">  
70 - <i class="material-icons">attach_file</i>  
71 - </button>  
72 - </span>  
73 - </div>  
74 - {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %}  
75 - <div class="checkbox">  
76 - <label for="{{ field.auto_id }}">  
77 - {% render_field field %} {{field.label}}  
78 - </label>  
79 - </div>  
80 - {% elif field.auto_id == 'id_cpf' %}  
81 - {% if field.field.required %}  
82 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
83 - {% else %}  
84 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
85 - {% endif %}  
86 - {% render_field field class='form-control' onkeypress='campoNumerico(this,event); formatarCpf(this,event);' %}  
87 -  
88 - {% elif field.auto_id == 'id_year_titration' %}  
89 - {% if field.field.required %}  
90 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
91 - {% else %}  
92 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
93 - {% endif %}  
94 - {% render_field field class='form-control' onkeypress='campoNumerico(this,event);' %}  
95 -  
96 - {% elif field.auto_id == 'id_phone' %}  
97 - {% if field.field.required %}  
98 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
99 - {% else %}  
100 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
101 - {% endif %}  
102 - {% render_field field class='form-control' onkeypress='campoNumerico(this,event); formatarTelefone(this,event);' %}  
103 - {% else %}  
104 - {% if field.field.required %}  
105 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label>  
106 - {% else %}  
107 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
108 - {% endif %}  
109 - {% render_field field class='form-control' %}  
110 - {% endif %}  
111 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
112 - {% if field.errors %}  
113 - <div class="alert alert-danger alert-dismissible" role="alert">  
114 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
115 - <span aria-hidden="true">&times;</span>  
116 - </button>  
117 - <ul>  
118 - {% for error in field.errors %}  
119 - <li>{{ error }}</li>  
120 - {% endfor %}  
121 - </ul>  
122 - </div>  
123 - {% endif %}  
124 - </div>  
125 - {% endfor %}  
126 - <div class="col-md-5 col-xs-6 col-sm-6 col-lg-5 text-center">  
127 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-success" onclick="validarCpfSemAlert(id_cpf, CPF, idElementoMensagemErro)'" />  
128 - </div>  
129 - <div class="col-md-5 col-xs-6 col-sm-6 col-lg-5 text-center">  
130 - <a href="{% url 'users:manage' %}" class="btn btn-raised btn-danger" >{% trans 'Cancel' %}</a>  
131 - </div>  
132 - </form> 14 + {% include 'users/_form.html' %}
133 </div> 15 </div>
134 </div> 16 </div>
135 - </div>  
136 -</br>  
137 -</br>  
138 -</br>  
139 -<script type="text/javascript">  
140 -var locale = navigator.language || navigator.userLanguage;  
141 -  
142 -$('.date-picker').datepicker({  
143 - language: locale,  
144 -});  
145 -</script> 17 + </div>
146 {% endblock %} 18 {% endblock %}
users/templates/users/edit_profile.html
@@ -69,11 +69,5 @@ @@ -69,11 +69,5 @@
69 </form> 69 </form>
70 </div> 70 </div>
71 </div> 71 </div>
72 - </div>  
73 - <br clear="all" />  
74 - <script type="text/javascript">  
75 - $('.text_wysiwyg').summernote({  
76 - height: 200  
77 - });  
78 - </script> 72 + </div>
79 {% endblock %} 73 {% endblock %}
users/templates/users/list.html 0 → 100644
@@ -0,0 +1,80 @@ @@ -0,0 +1,80 @@
  1 +{% extends 'base.html' %}
  2 +
  3 +{% load i18n pagination django_bootstrap_breadcrumbs permission_tags static %}
  4 +
  5 +{% block breadcrumbs %}
  6 + {{ block.super }}
  7 + {% breadcrumb 'Manage Users' 'users:manage' %}
  8 +{% endblock %}
  9 +
  10 +{% block menu %}
  11 +{% endblock %}
  12 +
  13 +{% block content %}
  14 + {% if messages %}
  15 + {% for message in messages %}
  16 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  17 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  18 + <span aria-hidden="true">&times;</span>
  19 + </button>
  20 + <p>{{ message }}</p>
  21 + </div>
  22 + {% endfor %}
  23 + {% endif %}
  24 +
  25 + <div class="row">
  26 + <div class="col-md-9">
  27 + <form action="" method="GET" class="form-horizontal">
  28 + <div class="form-group">
  29 + <div class="col-md-11 col-sm-11 col-xs-11">
  30 + <input type="text" class="form-control" name="search" placeholder="{% trans 'Search...' %}" />
  31 + </div>
  32 + <div class="col-md-1 col-sm-1 col-xs-1">
  33 + <button type="submit" class="btn btn-fab btn-fab-mini">
  34 + <i class="fa fa-search"></i>
  35 + </button>
  36 + </div>
  37 + </div>
  38 + </form>
  39 + </div>
  40 + <div class="col-md-3">
  41 + <a href="{% url 'users:create' %}" class="pull-right btn btn-primary btn-raised btn-md"><i class="fa fa-plus"></i> {% trans 'Create User' %}</a>
  42 + </div>
  43 + </div>
  44 +
  45 + {% if users %}
  46 + {% for acc in users %}
  47 + <div class="row-fluid panel panel-default">
  48 + <div class="panel-body">
  49 + <div class="col-md-3">
  50 + <span class="thumbnail">
  51 + <img src="{{ acc.image_url }}" class="img-responsive" />
  52 + </span>
  53 + </div>
  54 + <div class="col-md-6">
  55 + <p><b>{% trans 'Name' %}:</b> {{ acc }}</p>
  56 + <p><b>{% trans 'Email' %}:</b> {{ acc.email }}</p>
  57 + <p><b>{% trans 'Description' %}:</b>
  58 + {% autoescape off %}
  59 + {{ acc.description|default:_("Not Informed")|striptags|truncatechars:300 }}
  60 + {% endautoescape %}
  61 + </p>
  62 + </div>
  63 + <div class="col-md-3">
  64 + <div align="right">
  65 + <a href="{% url 'users:update' acc.email %}" class="btn btn-primary btn-raised btn-sm"><i class="fa fa-edit"></i> {% trans 'Edit' %}</a>
  66 + <a href="javascript:void(0)" class="btn btn-default btn-raised btn-sm" data-toggle="modal" data-target="#DeleteModal{{ forloop.counter }}"><i class="fa fa-trash"></i> {% trans 'Delete' %}</a>
  67 + </div>
  68 + </div>
  69 + </div>
  70 + </div>
  71 + {% endfor %}
  72 + {% pagination request paginator page_obj %}
  73 + {% else %}
  74 + <div class="row">
  75 + <div class="col-md-12 col-sm-12 col-xs-12">
  76 + <p>{% trans 'No users found' %}</p>
  77 + </div>
  78 + </div>
  79 + {% endif %}
  80 +{% endblock %}
users/templates/users/update.html
1 -{% extends 'list_users.html' %} 1 +{% extends 'users/list.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
@@ -28,63 +28,8 @@ @@ -28,63 +28,8 @@
28 <div class="card mg-b-5m"> 28 <div class="card mg-b-5m">
29 <div class="card-content"> 29 <div class="card-content">
30 <div class="card-body"> 30 <div class="card-body">
31 - <form method="post" action="" enctype="multipart/form-data">  
32 - {% csrf_token %}  
33 - {% for field in form %}  
34 - <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">  
35 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
36 - {% if field.auto_id == 'id_birth_date' %}  
37 - <input type="text" class="form-control date-picker"name="{{field.name}}" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}" id="{{ field.auto_id }}">  
38 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
39 - {% elif field.auto_id == 'id_image' or field.auto_id == 'id_curriculum'%}  
40 - {% render_field field class='form-control input-sm' %}  
41 - <div class="input-group">  
42 - <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">  
43 - <span class="input-group-btn input-group-sm">  
44 - <button type="button" class="btn btn-fab btn-fab-mini">  
45 - <i class="material-icons">attach_file</i>  
46 - </button>  
47 - </span>  
48 - </div>  
49 - {% elif field.auto_id == 'id_cpf' %}  
50 - {% render_field field class='form-control' onkeypress='campoNumerico(this,event); formatarCpf(this,event);' %}  
51 -  
52 - {% elif field.auto_id == 'id_phone' %}  
53 - {% render_field field class='form-control' onkeypress='campoNumerico(this,event); formatarTelefone(this,event);' %}  
54 -  
55 - {% elif field.auto_id == 'id_is_staff' or field.auto_id == 'id_is_active' %}  
56 - <div class="checkbox">  
57 - <label for="{{ field.auto_id }}">  
58 - {% render_field field %}<span class="checkbox-material"><span class="check"></span></span> {{field.label}}  
59 - </label>  
60 - </div>  
61 - {% else %}  
62 - {% render_field field class='form-control' %}  
63 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
64 - {% endif %}  
65 - {% if field.errors %}  
66 - <div class="alert alert-danger alert-dismissible" role="alert">  
67 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
68 - <span aria-hidden="true">&times;</span>  
69 - </button>  
70 - <ul>  
71 - {% for error in field.errors %}  
72 - <li>{{ error }}</li>  
73 - {% endfor %}  
74 - </ul>  
75 - </div>  
76 - {% endif %}  
77 - </div>  
78 - {% endfor %}  
79 - <div class="col-md-offset-2 col-md-2 col-sm-2 col-xs-2">  
80 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-success" />  
81 - </div>  
82 - <div class="col-md-offset-3 col-md-2 col-sm-2 col-xs-2">  
83 - <a href="{% url 'users:manage' %}" class="btn btn-raised btn-default" >{% trans 'Cancel' %}</a>  
84 - </div>  
85 - </form> 31 + {% include 'users/_form.html' %}
86 </div> 32 </div>
87 </div> 33 </div>
88 </div> 34 </div>
89 - <br clear="all" />  
90 {% endblock %} 35 {% endblock %}
@@ -7,6 +7,9 @@ urlpatterns = [ @@ -7,6 +7,9 @@ urlpatterns = [
7 url(r'^login/$', views.login, name='login'), 7 url(r'^login/$', views.login, name='login'),
8 url(r'^logout/$', auth_views.logout, {'next_page': 'users:login'}, name='logout'), 8 url(r'^logout/$', auth_views.logout, {'next_page': 'users:login'}, name='logout'),
9 url(r'^signup/$', views.RegisterUser.as_view(), name = 'signup'), 9 url(r'^signup/$', views.RegisterUser.as_view(), name = 'signup'),
  10 + url(r'^$', views.UsersListView.as_view(), name = 'manage'),
  11 + url(r'^edit/(?P<email>[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.UpdateView.as_view(), name='update'),
  12 + url(r'^create/$', views.CreateView.as_view(), name = 'create'),
10 url(r'^profile/$', views.Profile.as_view(), name = 'profile'), 13 url(r'^profile/$', views.Profile.as_view(), name = 'profile'),
11 url(r'^edit_profile/$', views.UpdateProfile.as_view(), name = 'edit_profile'), 14 url(r'^edit_profile/$', views.UpdateProfile.as_view(), name = 'edit_profile'),
12 ] 15 ]
users/views.py
@@ -14,7 +14,7 @@ from itertools import chain @@ -14,7 +14,7 @@ from itertools import chain
14 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 14 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
15 15
16 from .models import User 16 from .models import User
17 -from .forms import RegisterUserForm, ProfileForm 17 +from .forms import RegisterUserForm, ProfileForm, UserForm
18 18
19 #API IMPORTS 19 #API IMPORTS
20 from rest_framework import viewsets 20 from rest_framework import viewsets
@@ -22,93 +22,11 @@ from .serializers import UserSerializer @@ -22,93 +22,11 @@ from .serializers import UserSerializer
22 from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly 22 from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
23 23
24 # ================ ADMIN ======================= 24 # ================ ADMIN =======================
25 -# class UsersListView(HasRoleMixin, LoginRequiredMixin, generic.ListView):  
26 25
27 -# allowed_roles = ['system_admin']  
28 -# #login_url = reverse_lazy("core:home")  
29 -# redirect_field_name = 'next'  
30 -# template_name = 'list_users.html'  
31 -# context_object_name = 'users'  
32 -# paginate_by = 10  
33 -  
34 -# def get_queryset(self):  
35 -# search = self.request.GET.get('search', None)  
36 -  
37 -# if search is None:  
38 -# users = User.objects.all().order_by('name').exclude( username = self.request.user.username)  
39 -# else:  
40 -# users = User.objects.filter(Q(username = search) | Q(name = search) | Q(name__icontains = search) | Q(username__icontains = search)).exclude( username = self.request.user.username)  
41 -  
42 -# return users  
43 -  
44 -# def get_context_data (self, **kwargs):  
45 -# context = super(UsersListView, self).get_context_data(**kwargs)  
46 -# context['title'] = 'Manage Users'  
47 -# return context  
48 -  
49 -# class Create(HasRoleMixin, LoginRequiredMixin, generic.edit.CreateView):  
50 -  
51 -# allowed_roles = ['system_admin']  
52 -# #login_url = reverse_lazy("core:home")  
53 -# redirect_field_name = 'next'  
54 -# template_name = 'users/create.html'  
55 -# form_class = UserForm  
56 -# context_object_name = 'acc'  
57 -# success_url = reverse_lazy('users:manage')  
58 -  
59 -# def form_valid(self, form):  
60 -# self.object = form.save()  
61 -  
62 -# if self.object.type_profile == 2:  
63 -# assign_role(self.object, 'student')  
64 -# elif self.object.type_profile == 1:  
65 -# assign_role(self.object, 'professor')  
66 -# elif self.object.is_staff:  
67 -# assign_role(self.object, 'system_admin')  
68 26
69 -# self.object.save()  
70 27
71 -# messages.success(self.request, ('User ')+self.object.name+(' created successfully!'))  
72 28
73 -# return super(Create, self).form_valid(form)  
74 -# def get_context_data (self, **kwargs):  
75 -# context = super(Create, self).get_context_data(**kwargs)  
76 -# context['title'] = "Add User"  
77 -# return context  
78 29
79 -# class Update(HasRoleMixin, LoginRequiredMixin, generic.UpdateView):  
80 -  
81 -# allowed_roles = ['system_admin']  
82 -# #login_url = reverse_lazy("core:home")  
83 -# redirect_field_name = 'next'  
84 -# template_name = 'users/update.html'  
85 -# slug_field = 'username'  
86 -# slug_url_kwarg = 'username'  
87 -# context_object_name = 'acc'  
88 -# model = User  
89 -# form_class = UserForm  
90 -# success_url = reverse_lazy('users:manage')  
91 -  
92 -# def form_valid(self, form):  
93 -# self.object = form.save(commit = False)  
94 -  
95 -# if self.object.type_profile == 2:  
96 -# assign_role(self.object, 'student')  
97 -# elif self.object.type_profile == 1:  
98 -# assign_role(self.object, 'professor')  
99 -# elif self.object.is_staff:  
100 -# assign_role(self.object, 'system_admin')  
101 -  
102 -# self.object.save()  
103 -  
104 -# messages.success(self.request, _('User ')+self.object.name+_(' updated successfully!'))  
105 -  
106 -# return super(Update, self).form_valid(form)  
107 -  
108 -# def get_context_data (self, **kwargs):  
109 -# context = super(Update, self).get_context_data(**kwargs)  
110 -# context['title'] = "Update User"  
111 -# return context  
112 30
113 # class View(LoginRequiredMixin, generic.DetailView): 31 # class View(LoginRequiredMixin, generic.DetailView):
114 32
@@ -182,6 +100,85 @@ from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnl @@ -182,6 +100,85 @@ from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnl
182 100
183 # return context 101 # return context
184 102
  103 +class UsersListView(LoginRequiredMixin, generic.ListView):
  104 + login_url = reverse_lazy("users:login")
  105 + redirect_field_name = 'next'
  106 +
  107 + template_name = 'users/list.html'
  108 + context_object_name = 'users'
  109 + paginate_by = 10
  110 +
  111 + def get_queryset(self):
  112 + users = User.objects.all().order_by('social_name','username').exclude(email = self.request.user.email)
  113 +
  114 + return users
  115 +
  116 + def get_context_data (self, **kwargs):
  117 + context = super(UsersListView, self).get_context_data(**kwargs)
  118 + context['title'] = _('Manage Users')
  119 +
  120 + return context
  121 +
  122 +class CreateView(LoginRequiredMixin, generic.edit.CreateView):
  123 + login_url = reverse_lazy("users:login")
  124 + redirect_field_name = 'next'
  125 +
  126 + template_name = 'users/create.html'
  127 + form_class = UserForm
  128 + context_object_name = 'acc'
  129 + success_url = reverse_lazy('users:manage')
  130 +
  131 + def form_valid(self, form):
  132 + self.object = form.save()
  133 +
  134 + msg = _("User %s created successfully" % self.object.get_short_name())
  135 +
  136 + messages.success(self.request, msg)
  137 +
  138 + return super(CreateView, self).form_valid(form)
  139 +
  140 + def get_context_data (self, **kwargs):
  141 + context = super(CreateView, self).get_context_data(**kwargs)
  142 + context['title'] = _("Add User")
  143 +
  144 + return context
  145 +
  146 +class UpdateView(LoginRequiredMixin, generic.UpdateView):
  147 + login_url = reverse_lazy("users:login")
  148 + redirect_field_name = 'next'
  149 +
  150 + template_name = 'users/update.html'
  151 + slug_field = 'email'
  152 + slug_url_kwarg = 'email'
  153 + context_object_name = 'acc'
  154 + model = User
  155 + form_class = UserForm
  156 + success_url = reverse_lazy('users:manage')
  157 +
  158 + def get_form_kwargs(self):
  159 + kwargs = super(UpdateView, self).get_form_kwargs()
  160 +
  161 + kwargs.update({'is_edit': True})
  162 +
  163 + return kwargs
  164 +
  165 + def form_valid(self, form):
  166 + self.object = form.save(commit = False)
  167 +
  168 + self.object.save()
  169 +
  170 + msg = _("User %s updated successfully" % self.object.get_short_name())
  171 +
  172 + messages.success(self.request, msg)
  173 +
  174 + return super(UpdateView, self).form_valid(form)
  175 +
  176 + def get_context_data (self, **kwargs):
  177 + context = super(UpdateView, self).get_context_data(**kwargs)
  178 + context['title'] = _("Update User")
  179 +
  180 + return context
  181 +
185 class Profile(LoginRequiredMixin, generic.DetailView): 182 class Profile(LoginRequiredMixin, generic.DetailView):
186 login_url = reverse_lazy("users:login") 183 login_url = reverse_lazy("users:login")
187 redirect_field_name = 'next' 184 redirect_field_name = 'next'