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 107 <li title data-original-title="{% trans 'settings' %}">
108 108 <a href="" data-toggle="dropdown"><i class="fa fa-cog" aria-hidden="true"></i></a>
109 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 112 </ul>
115 113 </li>
116 114 <li>
... ... @@ -171,6 +169,11 @@
171 169  
172 170 <!-- Init material Bootstrap -->
173 171 <script type="text/javascript">$.material.init()</script>
  172 + <script type="text/javascript">
  173 + $('.text_wysiwyg').summernote({
  174 + height: 200
  175 + });
  176 + </script>
174 177 </body>
175 178  
176 179 </html>
177 180 \ No newline at end of file
... ...
amadeus/templates/pagination.html 0 → 100644
... ... @@ -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 12 \ No newline at end of file
... ...
amadeus/templatetags/__init__.py 0 → 100644
amadeus/templatetags/pagination.py 0 → 100644
... ... @@ -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 22 \ No newline at end of file
... ...
users/forms.py
... ... @@ -86,4 +86,40 @@ class ProfileForm(Validation):
86 86 fields = ['social_name', 'description', 'show_email', 'image']
87 87 widgets = {
88 88 'description': forms.Textarea,
89   - }
90 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 127 \ No newline at end of file
... ...
users/migrations/0003_auto_20161222_1505.py 0 → 100644
... ... @@ -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 29 image = models.ImageField(verbose_name = _('Photo'), null=True, blank = True, upload_to = 'users/', validators = [validate_img_extension])
30 30 date_created = models.DateTimeField(_('Create Date'), auto_now_add = True)
31 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 33 is_staff = models.BooleanField(_('Administrator'), default = False)
34 34 is_active = models.BooleanField(_('Active'), default = True)
35 35  
... ... @@ -46,7 +46,7 @@ class User(AbstractBaseUser, PermissionsMixin):
46 46 return self.social_name or self.username
47 47  
48 48 def get_short_name(self):
49   - return self.username
  49 + return str(self)
50 50  
51 51 @property
52 52 def image_url(self):
... ...
users/templates/list_users.html
... ... @@ -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 @@
  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 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 3 {% load django_bootstrap_breadcrumbs %}
7 4  
8 5 {% block breadcrumbs %}
9   -
10   - {{ block.super }}
  6 + {{ block.super }}
11 7 {% breadcrumb 'Add User' 'users:create' %}
12   -
13 8 {% endblock %}
14 9  
15   -
16 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 11 <div class="card">
29 12 <div class="card-content">
30 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 15 </div>
134 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 18 {% endblock %}
... ...
users/templates/users/edit_profile.html
... ... @@ -69,11 +69,5 @@
69 69 </form>
70 70 </div>
71 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 73 {% endblock %}
... ...
users/templates/users/list.html 0 → 100644
... ... @@ -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 3 {% load static i18n %}
4 4 {% load widget_tweaks %}
... ... @@ -28,63 +28,8 @@
28 28 <div class="card mg-b-5m">
29 29 <div class="card-content">
30 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 32 </div>
87 33 </div>
88 34 </div>
89   - <br clear="all" />
90 35 {% endblock %}
... ...
users/urls.py
... ... @@ -7,6 +7,9 @@ urlpatterns = [
7 7 url(r'^login/$', views.login, name='login'),
8 8 url(r'^logout/$', auth_views.logout, {'next_page': 'users:login'}, name='logout'),
9 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 13 url(r'^profile/$', views.Profile.as_view(), name = 'profile'),
11 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 14 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
15 15  
16 16 from .models import User
17   -from .forms import RegisterUserForm, ProfileForm
  17 +from .forms import RegisterUserForm, ProfileForm, UserForm
18 18  
19 19 #API IMPORTS
20 20 from rest_framework import viewsets
... ... @@ -22,93 +22,11 @@ from .serializers import UserSerializer
22 22 from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
23 23  
24 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 31 # class View(LoginRequiredMixin, generic.DetailView):
114 32  
... ... @@ -182,6 +100,85 @@ from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnl
182 100  
183 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 182 class Profile(LoginRequiredMixin, generic.DetailView):
186 183 login_url = reverse_lazy("users:login")
187 184 redirect_field_name = 'next'
... ...