Browse Source

Refatora interface de Administração de Usuários (#2517)

* Implementar pesquisa de usuário

Adequar layouts dos botões

Adicionar confirmação para deletar usuário

Adicionar success_message ao deletar

Capturar e tratar ProtectedError em DeleteUsuario

Subir pequena alteração

Atualizar self.form.helper

* Update sapl/base/views.py

Co-Authored-By: rjoao <cont.joaorodrigues@gmail.com>

* Atualizar sapl/base/views.py
pull/2527/head
João Rodrigues 6 years ago
committed by Edward
parent
commit
5e89f9513e
  1. 30
      sapl/base/forms.py
  2. 4
      sapl/base/urls.py
  3. 105
      sapl/base/views.py
  4. 51
      sapl/templates/auth/user_filter.html
  5. 11
      sapl/templates/auth/user_form.html
  6. 35
      sapl/templates/auth/user_list.html
  7. 2
      sapl/templates/navbar.yaml

30
sapl/base/forms.py

@ -112,8 +112,6 @@ class UsuarioCreateForm(ModelForm):
[('password1', 6),
('password2', 6)])
row4 = to_row([(form_actions(label='Confirmar'), 6)])
self.helper = SaplFormHelper()
self.helper.layout = Layout(
row0,
@ -121,7 +119,31 @@ class UsuarioCreateForm(ModelForm):
row3,
row2,
'roles',
row4)
form_actions(label='Confirmar'))
class UsuarioFilterSet(django_filters.FilterSet):
username = django_filters.CharFilter(
label=_('Nome de Usuário'),
lookup_expr='icontains')
class Meta:
model = User
fields = ['username']
def __init__(self, *args, **kwargs):
super(UsuarioFilterSet, self).__init__(*args, **kwargs)
row0 = to_row([('username', 12)])
self.form.helper = SaplFormHelper()
self.form.helper.form_method = 'GET'
self.form.helper.layout = Layout(
Fieldset(_('Pesquisa de Usuário'),
row0,
form_actions(label='Pesquisar'))
)
class UsuarioEditForm(ModelForm):
@ -159,7 +181,7 @@ class UsuarioEditForm(ModelForm):
row1,
row2,
'roles',
row3)
form_actions(label='Salvar Alterações'))
def clean(self):
super(UsuarioEditForm, self).clean()

4
sapl/base/urls.py

@ -15,7 +15,7 @@ from .apps import AppConfig
from .forms import LoginForm, NovaSenhaForm, RecuperarSenhaForm
from .views import (AlterarSenha, AppConfigCrud, CasaLegislativaCrud,
CreateUsuarioView, DeleteUsuarioView, EditUsuarioView,
HelpTopicView, ListarUsuarioView, LogotipoView,
HelpTopicView, PesquisarUsuarioView, LogotipoView,
RelatorioAtasView, RelatorioAudienciaView,
RelatorioDataFimPrazoTramitacaoView,
RelatorioHistoricoTramitacaoView,
@ -41,7 +41,7 @@ from .views import (AlterarSenha, AppConfigCrud, CasaLegislativaCrud,
app_name = AppConfig.name
admin_user = [
url(r'^sistema/usuario/$', ListarUsuarioView.as_view(), name='user_list'),
url(r'^sistema/usuario/$', PesquisarUsuarioView.as_view(), name='usuario'),
url(r'^sistema/usuario/create$', CreateUsuarioView.as_view(), name='user_create'),
url(r'^sistema/usuario/(?P<pk>\d+)/edit$', EditUsuarioView.as_view(), name='user_edit'),
url(r'^sistema/usuario/(?P<pk>\d+)/delete$', DeleteUsuarioView.as_view(), name='user_delete')

105
sapl/base/views.py

@ -4,15 +4,16 @@ import datetime
import logging
import os
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.models import Group
from django.contrib.auth.models import Group, User
from django.contrib.auth.tokens import default_token_generator
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse, reverse_lazy
from django.db import connection
from django.db.models import Count, Q
from django.db.models import Count, Q, ProtectedError
from django.http import Http404, HttpResponseRedirect
from django.template import TemplateDoesNotExist
from django.template.loader import get_template
@ -56,7 +57,7 @@ from .forms import (AlterarSenhaForm, CasaLegislativaForm,
RelatorioReuniaoFilterSet, UsuarioCreateForm,
UsuarioEditForm, RelatorioNormasMesFilterSet,
RelatorioNormasVigenciaFilterSet,
EstatisticasAcessoNormasForm)
EstatisticasAcessoNormasForm, UsuarioFilterSet)
from .models import AppConfig, CasaLegislativa
@ -1266,35 +1267,72 @@ class ListarProtocolosDuplicadosView(PermissionRequiredMixin, ListView):
return context
class ListarUsuarioView(PermissionRequiredMixin, ListView):
model = get_user_model()
template_name = 'auth/user_list.html'
context_object_name = 'user_list'
class PesquisarUsuarioView(PermissionRequiredMixin, FilterView):
model = User
filterset_class = UsuarioFilterSet
permission_required = ('base.list_appconfig',)
paginate_by = 10
def get_queryset(self):
qs = super(ListarUsuarioView, self).get_queryset()
return qs.order_by('username')
def get_filterset_kwargs(self, filterset_class):
super(PesquisarUsuarioView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
qs = self.get_queryset().order_by('username').distinct()
kwargs.update({
'queryset': qs,
})
return kwargs
def get_context_data(self, **kwargs):
context = super(ListarUsuarioView, self).get_context_data(**kwargs)
context = super(PesquisarUsuarioView,
self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['NO_ENTRIES_MSG'] = 'Nenhum usuário cadastrado.'
context['NO_ENTRIES_MSG'] = 'Nenhum usuário encontrado!'
context['title'] = _('Usuários')
return context
def get(self, request, *args, **kwargs):
super(PesquisarUsuarioView, self).get(request)
data = self.filterset.data
url = ''
if data:
url = "&" + str(self.request.environ['QUERY_STRING'])
if url.startswith("&page"):
ponto_comeco = url.find('username=') - 1
url = url[ponto_comeco:]
context = self.get_context_data(filter=self.filterset,
object_list=self.object_list,
filter_url=url,
numero_res=len(self.object_list)
)
context['show_results'] = show_results_filter_set(
self.request.GET.copy())
return self.render_to_response(context)
class CreateUsuarioView(PermissionRequiredMixin, CreateView):
model = get_user_model()
form_class = UsuarioCreateForm
success_message = 'Usuário criado com sucesso'
success_message = 'Usuário criado com sucesso!'
permission_required = ('base.add_appconfig',)
def get_success_url(self):
return reverse('sapl.base:user_list')
return reverse('sapl.base:usuario')
def form_valid(self, form):
@ -1313,33 +1351,49 @@ class CreateUsuarioView(PermissionRequiredMixin, CreateView):
for g in groups:
g.user_set.add(new_user)
messages.success(self.request, self.success_message)
return HttpResponseRedirect(self.get_success_url())
class DeleteUsuarioView(PermissionRequiredMixin, DeleteView):
model = get_user_model()
template_name = "crud/confirm_delete.html"
permission_required = ('base.delete_appconfig',)
success_url = reverse_lazy('sapl.base:usuario')
success_message = "Usuário removido com sucesso!"
def get_success_url(self):
return reverse('sapl.base:user_list')
def delete(self, request, *args, **kwargs):
try:
super(DeleteUsuarioView, self).delete(request, *args, **kwargs)
except ProtectedError as exception:
error_url = reverse_lazy('sapl.base:user_delete', kwargs={'pk': self.kwargs['pk']})
error_message = "O usuário não pode ser removido, pois é referenciado por:<br><ul>"
def get(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)
for e in exception.protected_objects:
error_message += '<li>{} - {}</li>'.format(
e._meta.verbose_name, e
)
error_message += '</ul>'
messages.error(self.request, error_message)
return HttpResponseRedirect(error_url)
def get_queryset(self):
qs = super(DeleteUsuarioView, self).get_queryset()
return qs.filter(id=self.kwargs['pk'])
messages.success(self.request, self.success_message)
return HttpResponseRedirect(self.success_url)
@property
def cancel_url(self):
return reverse('sapl.base:user_edit',
kwargs={'pk': self.kwargs['pk']})
class EditUsuarioView(PermissionRequiredMixin, UpdateView):
model = get_user_model()
form_class = UsuarioEditForm
success_message = 'Usuário editado com sucesso'
success_message = 'Usuário editado com sucesso!'
permission_required = ('base.change_appconfig',)
def get_success_url(self):
return reverse('sapl.base:user_list')
return reverse('sapl.base:usuario')
def get_initial(self):
initial = super(EditUsuarioView, self).get_initial()
@ -1376,6 +1430,7 @@ class EditUsuarioView(PermissionRequiredMixin, UpdateView):
for g in groups:
g.user_set.add(user)
messages.success(self.request, self.success_message)
return super(EditUsuarioView, self).form_valid(form)

51
sapl/templates/auth/user_filter.html

@ -0,0 +1,51 @@
{% extends "crud/list.html" %}
{% load i18n %}
{% load crispy_forms_tags staticfiles %}
{% block base_content %}
{% if not show_results %}
{% crispy filter.form %}
<a href="{% url 'sapl.base:user_create' %}" class="btn btn-outline-primary">{% trans 'Criar usuário' %}</a>
{% endif %}
{% if show_results %}
<div class="actions btn-group float-right" role="group">
<a href="{% url 'sapl.base:usuario' %}" class="btn btn-outline-primary">{% trans 'Fazer nova pesquisa' %}</a>
<a href="{% url 'sapl.base:user_create' %}" class="btn btn-outline-primary">{% trans 'Criar usuário' %}</a>
</div>
<br /><br />
{% if numero_res > 0 %}
{% if numero_res == 1 %}
<p>Foi encontrado {{ numero_res }} resultado</p>
{% else %}
<p>Foram encontrados {{ numero_res }} resultados</p>
{% endif %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Nome de Usuário</th>
<th>Nome</th>
<th>E-mail do Usuário</th>
</tr>
</thead>
<tbody>
{% for usuario in page_obj %}
<tr>
<td>
<a href="{% url 'sapl.base:user_edit' usuario.pk %}">{{ usuario.username }}</a>
</td>
<td>{{ usuario.first_name }} {{ usuario.last_name }}</td>
<td>{{ usuario.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<font size="4"><p align="center">{{ NO_ENTRIES_MSG }}</p></font>
{% endif %}
{% endif %}
<br/>
{% include 'paginacao.html'%}
<br /><br /><br />
{% endblock base_content %}

11
sapl/templates/auth/user_form.html

@ -5,10 +5,15 @@
<form action="" method="post">
{% csrf_token %}
{% crispy form %}
{% if object.pk %}
<a class="btn btn-warning" href="{% url 'sapl.base:user_delete' object.pk %}">Remover usuário</a>
<div class="actions btn-group float-left" role="group">
<a href="{% url 'sapl.base:usuario' %}" class="btn btn-outline-primary">{% trans 'Pesquisar usuários' %}</a>
<a href="{% url 'sapl.base:user_create' %}" class="btn btn-outline-primary">{% trans 'Criar usuário' %}</a>
</div>
<a href="{% url 'sapl.base:user_delete' object.pk %}" class="btn btn-outline-danger float-right">{% trans 'Remover usuário' %}</a>
<br /> <br />
{% endif %}
{% crispy form %}
</form>
<br /><br /><br />
{% endblock base_content %}

35
sapl/templates/auth/user_list.html

@ -1,35 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% load tz %}
{% load common_tags %}
{% block base_content %}
<fieldset>
<h1>Lista de usuários</h1>
{% if not user_list %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Nome de Login</th>
<th>Nome</th>
<th>E-mail do Usuário</th>
</tr>
</thead>
<tbody>
{% for user in user_list %}
<tr>
<td>
<a href="{% url 'sapl.base:user_edit' user.pk %}">{{ user.username }}</a>
</td>
<td>{{ user.first_name }} {{ user.last_name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
<a class="btn btn-outline-primary" href="{% url 'sapl.base:user_create' %}">Criar Usuário</a>
</fieldset>
{% include 'paginacao.html'%}
{% endblock base_content %}

2
sapl/templates/navbar.yaml

@ -73,7 +73,7 @@
url: '/sistema'
check_permission: base.view_tabelas_auxiliares
- title: {% trans 'Administração de Usuários' %}
url: {% url 'sapl.base:user_list' %}
url: {% url 'sapl.base:usuario' %}
check_permission: user.is_superuser
- title: {% trans 'Inconsistências da Aplicação' %}
url: {% url 'sapl.base:lista_inconsistencias' %}

Loading…
Cancel
Save