Commit e9ee55cc by Bach Dániel

dashboard: add user list view

parent 30d8fe06
......@@ -1494,3 +1494,10 @@ class TemplateListSearchForm(forms.Form):
data = self.data.copy()
data['stype'] = "owned"
self.data = data
class UserListSearchForm(forms.Form):
s = forms.CharField(widget=forms.TextInput(attrs={
'class': "form-control input-tags",
'placeholder': _("Search...")
}))
......@@ -123,26 +123,24 @@ class GroupListTable(Table):
class UserListTable(Table):
pk = TemplateColumn(
template_name='dashboard/vm-list/column-id.html',
verbose_name="ID",
attrs={'th': {'class': 'vm-list-table-thin'}},
username = LinkColumn(
'dashboard.views.profile',
args=[A('username')],
)
username = TemplateColumn(
template_name="dashboard/group-list/column-username.html"
profile__org_id = LinkColumn(
'dashboard.views.profile',
accessor='profile.org_id',
args=[A('username')],
verbose_name=_('Organization ID')
)
is_superuser = BooleanColumn()
is_active = BooleanColumn()
class Meta:
model = User
attrs = {'class': ('table table-bordered table-striped table-hover '
'vm-list-table')}
fields = ('pk', 'username', )
class UserListTablex(Table):
class Meta:
model = User
attrs = {'class': ('table table-bordered table-striped table-hover')}
fields = ('username', 'last_name', 'first_name', 'profile__org_id',
'email', 'is_active', 'is_superuser')
class TemplateListTable(Table):
......
{% load i18n %}
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right toolbar">
<span class="btn btn-default btn-xs infobtn" data-container="body" title="{% trans "List of CIRCLE users." %}"><i class="fa fa-info-circle"></i></span>
</div>
<h3 class="no-margin"><i class="fa fa-users"></i> {% trans "Users" %}</h3>
</div>
<div class="list-group" id="user-list-view">
<div id="dashboard-user-list">
{% for i in users %}
<a href="{% url "dashboard.views.profile" username=i.username %}" class="list-group-item real-link
{% if forloop.last and users|length < 5 %} list-group-item-last{% endif %}">
<i class="fa fa-user"></i> {% firstof i.get_full_name|safe i.username|safe %}
</a>
{% endfor %}
</div>
<div class="list-group-item list-group-footer text-right">
<div class="row">
<div class="col-xs-6">
<form action="{% url "dashboard.views.user-list" %}" method="GET" id="dashboard-user-search-form">
<div class="input-group input-group-sm">
<input id="dashboard-group-search-input" name="s" type="text" class="form-control" placeholder="{% trans "Search..." %}" />
<div class="input-group-btn">
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
</div>
<div class="col-xs-6 text-right">
<a class="btn btn-primary btn-xs" href="{% url "dashboard.views.user-list" %}">
<i class="fa fa-chevron-circle-right"></i>
{% if more_users > 0 %}
{% blocktrans count more=more_users %}
<strong>{{ more }}</strong> more
{% plural %}
<strong>{{ more }}</strong> more
{% endblocktrans %}
{% else %}
{% trans "list" %}
{% endif %}
</a>
<a class="btn btn-success btn-xs user-create" href="{% url "dashboard.views.group-create" %}"><i class="fa fa-plus-circle"></i> {% trans "new" %} </a>
</div>
</div>
</div>
</div>
</div>
......@@ -48,6 +48,12 @@
{% include "dashboard/index-nodes.html" %}
</div>
{% endif %}
{% if perms.auth.change_user %}
<div class="col-lg-4 col-sm-6">
{% include "dashboard/index-users.html" %}
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load staticfiles %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block title-page %}{% trans "Users" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<a href="{% url "dashboard.views.template-choose" %}" class="pull-right btn btn-success btn-xs template-choose">
<i class="fa fa-plus"></i> {% trans "new user" %}
</a>
<h3 class="no-margin"><i class="fa fa-user"></i> {% trans "Users" %}</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-offset-8 col-md-4" id="template-list-search">
<form action="" method="GET">
<div class="input-group">
{{ search_form.s }}
<div class="input-group-btn">
{{ search_form.stype }}
<button type="submit" class="btn btn-primary input-tags">
<i class="fa fa-search"></i>
</button>
</div>
</div><!-- .input-group -->
</form>
</div><!-- .col-md-4 #template-list-search -->
</div>
</div>
<div class="panel-body">
<div class="table-responsive">
{% render_table table %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
......@@ -52,6 +52,7 @@ from .views import (
TransferTemplateOwnershipView, TransferTemplateOwnershipConfirmView,
OpenSearchDescriptionView,
NodeActivityView,
UserList,
)
from .views.vm import vm_ops, vm_mass_ops
from .views.node import node_ops
......@@ -61,6 +62,8 @@ autocomplete_light.autodiscover()
urlpatterns = patterns(
'',
url(r'^$', IndexView.as_view(), name="dashboard.index"),
url(r"^profile/list/$", UserList.as_view(),
name="dashboard.views.user-list"),
url(r'^lease/(?P<pk>\d+)/$', LeaseDetail.as_view(),
name="dashboard.views.lease-detail"),
url(r'^lease/create/$', LeaseCreate.as_view(),
......
......@@ -21,7 +21,7 @@ import logging
from django.core.cache import get_cache
from django.core.urlresolvers import reverse
from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.auth.models import Group, User
from django.views.generic import TemplateView
from braces.views import LoginRequiredMixin
......@@ -86,6 +86,14 @@ class IndexView(LoginRequiredMixin, TemplateView):
'more_groups': groups.count() - len(groups[:5]),
})
# users
if user.has_module_perms('auth.change_user'):
users = User.objects.all()
context.update({
'users': users[:5],
'more_users': users.count() - len(users[:5]),
})
# template
if user.has_perm('vm.create_template'):
context['templates'] = InstanceTemplate.get_objects_with_level(
......
......@@ -31,6 +31,7 @@ from django.core.exceptions import (
)
from django.core.urlresolvers import reverse, reverse_lazy
from django.core.paginator import Paginator, InvalidPage
from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import redirect, get_object_or_404
from django.utils.translation import ugettext as _
......@@ -42,14 +43,19 @@ from django_sshkey.models import UserKey
from braces.views import LoginRequiredMixin, PermissionRequiredMixin
from django_tables2 import SingleTableView
from vm.models import Instance, InstanceTemplate
from ..forms import (
CircleAuthenticationForm, MyProfileForm, UserCreationForm, UnsubscribeForm,
UserKeyForm, CirclePasswordChangeForm, ConnectCommandForm,
UserListSearchForm,
)
from ..models import Profile, GroupProfile, ConnectCommand, create_profile
from ..tables import UserKeyListTable, ConnectCommandListTable
from ..tables import (
UserKeyListTable, ConnectCommandListTable, UserListTable,
)
from .util import saml_available, DeleteViewBase
......@@ -480,3 +486,46 @@ class ConnectCommandCreate(LoginRequiredMixin, SuccessMessageMixin,
kwargs = super(ConnectCommandCreate, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
class UserList(LoginRequiredMixin, PermissionRequiredMixin, SingleTableView):
template_name = "dashboard/user-list.html"
permission_required = "auth.change_user"
model = User
table_class = UserListTable
table_pagination = True
def get_context_data(self, *args, **kwargs):
context = super(UserList, self).get_context_data(*args, **kwargs)
context['search_form'] = self.search_form
return context
def get(self, *args, **kwargs):
self.search_form = UserListSearchForm(self.request.GET)
self.search_form.full_clean()
if self.request.is_ajax():
users = [
{'url': reverse("dashboard.views.profile", args=[i.username]),
'name': i.get_full_name() or i.username}
for i in self.get_queryset()]
return HttpResponse(
json.dumps(users), content_type="application/json")
else:
return super(UserList, self).get(*args, **kwargs)
def get_queryset(self):
logger.debug('UserList.get_queryset() called. User: %s',
unicode(self.request.user))
qs = User.objects.all()
q = self.search_form.cleaned_data.get('s')
if q:
filters = (Q(username__icontains=q) | Q(email__icontains=q)
| Q(profile__org_id__icontains=q))
for w in q.split()[:3]:
filters |= (
Q(first_name__icontains=w) | Q(last_name__icontains=w))
qs = qs.filter(filters)
return qs.select_related("profile")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment