Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
e9ee55cc
authored
Jan 13, 2015
by
Bach Dániel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add user list view
parent
30d8fe06
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
181 additions
and
17 deletions
+181
-17
circle/dashboard/forms.py
+7
-0
circle/dashboard/tables.py
+13
-15
circle/dashboard/templates/dashboard/index-users.html
+48
-0
circle/dashboard/templates/dashboard/index.html
+6
-0
circle/dashboard/templates/dashboard/user-list.html
+45
-0
circle/dashboard/urls.py
+3
-0
circle/dashboard/views/index.py
+9
-1
circle/dashboard/views/user.py
+50
-1
No files found.
circle/dashboard/forms.py
View file @
e9ee55cc
...
@@ -1494,3 +1494,10 @@ class TemplateListSearchForm(forms.Form):
...
@@ -1494,3 +1494,10 @@ class TemplateListSearchForm(forms.Form):
data
=
self
.
data
.
copy
()
data
=
self
.
data
.
copy
()
data
[
'stype'
]
=
"owned"
data
[
'stype'
]
=
"owned"
self
.
data
=
data
self
.
data
=
data
class
UserListSearchForm
(
forms
.
Form
):
s
=
forms
.
CharField
(
widget
=
forms
.
TextInput
(
attrs
=
{
'class'
:
"form-control input-tags"
,
'placeholder'
:
_
(
"Search..."
)
}))
circle/dashboard/tables.py
View file @
e9ee55cc
...
@@ -123,26 +123,24 @@ class GroupListTable(Table):
...
@@ -123,26 +123,24 @@ class GroupListTable(Table):
class
UserListTable
(
Table
):
class
UserListTable
(
Table
):
pk
=
TemplateColumn
(
username
=
LinkColumn
(
template_name
=
'dashboard/vm-list/column-id.html'
,
'dashboard.views.profile'
,
verbose_name
=
"ID"
,
args
=
[
A
(
'username'
)],
attrs
=
{
'th'
:
{
'class'
:
'vm-list-table-thin'
}},
)
)
profile__org_id
=
LinkColumn
(
username
=
TemplateColumn
(
'dashboard.views.profile'
,
template_name
=
"dashboard/group-list/column-username.html"
accessor
=
'profile.org_id'
,
args
=
[
A
(
'username'
)],
verbose_name
=
_
(
'Organization ID'
)
)
)
is_superuser
=
BooleanColumn
()
is_active
=
BooleanColumn
()
class
Meta
:
class
Meta
:
model
=
User
model
=
User
attrs
=
{
'class'
:
(
'table table-bordered table-striped table-hover '
attrs
=
{
'class'
:
(
'table table-bordered table-striped table-hover'
)}
'vm-list-table'
)}
fields
=
(
'username'
,
'last_name'
,
'first_name'
,
'profile__org_id'
,
fields
=
(
'pk'
,
'username'
,
)
'email'
,
'is_active'
,
'is_superuser'
)
class
UserListTablex
(
Table
):
class
Meta
:
model
=
User
class
TemplateListTable
(
Table
):
class
TemplateListTable
(
Table
):
...
...
circle/dashboard/templates/dashboard/index-users.html
0 → 100644
View file @
e9ee55cc
{% 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>
circle/dashboard/templates/dashboard/index.html
View file @
e9ee55cc
...
@@ -48,6 +48,12 @@
...
@@ -48,6 +48,12 @@
{% include "dashboard/index-nodes.html" %}
{% include "dashboard/index-nodes.html" %}
</div>
</div>
{% endif %}
{% endif %}
{% if perms.auth.change_user %}
<div
class=
"col-lg-4 col-sm-6"
>
{% include "dashboard/index-users.html" %}
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
{% endblock %}
circle/dashboard/templates/dashboard/user-list.html
0 → 100644
View file @
e9ee55cc
{% 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 %}
circle/dashboard/urls.py
View file @
e9ee55cc
...
@@ -52,6 +52,7 @@ from .views import (
...
@@ -52,6 +52,7 @@ from .views import (
TransferTemplateOwnershipView
,
TransferTemplateOwnershipConfirmView
,
TransferTemplateOwnershipView
,
TransferTemplateOwnershipConfirmView
,
OpenSearchDescriptionView
,
OpenSearchDescriptionView
,
NodeActivityView
,
NodeActivityView
,
UserList
,
)
)
from
.views.vm
import
vm_ops
,
vm_mass_ops
from
.views.vm
import
vm_ops
,
vm_mass_ops
from
.views.node
import
node_ops
from
.views.node
import
node_ops
...
@@ -61,6 +62,8 @@ autocomplete_light.autodiscover()
...
@@ -61,6 +62,8 @@ autocomplete_light.autodiscover()
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
''
,
''
,
url
(
r'^$'
,
IndexView
.
as_view
(),
name
=
"dashboard.index"
),
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
(),
url
(
r'^lease/(?P<pk>\d+)/$'
,
LeaseDetail
.
as_view
(),
name
=
"dashboard.views.lease-detail"
),
name
=
"dashboard.views.lease-detail"
),
url
(
r'^lease/create/$'
,
LeaseCreate
.
as_view
(),
url
(
r'^lease/create/$'
,
LeaseCreate
.
as_view
(),
...
...
circle/dashboard/views/index.py
View file @
e9ee55cc
...
@@ -21,7 +21,7 @@ import logging
...
@@ -21,7 +21,7 @@ import logging
from
django.core.cache
import
get_cache
from
django.core.cache
import
get_cache
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.conf
import
settings
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
django.views.generic
import
TemplateView
from
braces.views
import
LoginRequiredMixin
from
braces.views
import
LoginRequiredMixin
...
@@ -86,6 +86,14 @@ class IndexView(LoginRequiredMixin, TemplateView):
...
@@ -86,6 +86,14 @@ class IndexView(LoginRequiredMixin, TemplateView):
'more_groups'
:
groups
.
count
()
-
len
(
groups
[:
5
]),
'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
# template
if
user
.
has_perm
(
'vm.create_template'
):
if
user
.
has_perm
(
'vm.create_template'
):
context
[
'templates'
]
=
InstanceTemplate
.
get_objects_with_level
(
context
[
'templates'
]
=
InstanceTemplate
.
get_objects_with_level
(
...
...
circle/dashboard/views/user.py
View file @
e9ee55cc
...
@@ -31,6 +31,7 @@ from django.core.exceptions import (
...
@@ -31,6 +31,7 @@ from django.core.exceptions import (
)
)
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.core.paginator
import
Paginator
,
InvalidPage
from
django.core.paginator
import
Paginator
,
InvalidPage
from
django.db.models
import
Q
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.shortcuts
import
redirect
,
get_object_or_404
from
django.shortcuts
import
redirect
,
get_object_or_404
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
...
@@ -42,14 +43,19 @@ from django_sshkey.models import UserKey
...
@@ -42,14 +43,19 @@ from django_sshkey.models import UserKey
from
braces.views
import
LoginRequiredMixin
,
PermissionRequiredMixin
from
braces.views
import
LoginRequiredMixin
,
PermissionRequiredMixin
from
django_tables2
import
SingleTableView
from
vm.models
import
Instance
,
InstanceTemplate
from
vm.models
import
Instance
,
InstanceTemplate
from
..forms
import
(
from
..forms
import
(
CircleAuthenticationForm
,
MyProfileForm
,
UserCreationForm
,
UnsubscribeForm
,
CircleAuthenticationForm
,
MyProfileForm
,
UserCreationForm
,
UnsubscribeForm
,
UserKeyForm
,
CirclePasswordChangeForm
,
ConnectCommandForm
,
UserKeyForm
,
CirclePasswordChangeForm
,
ConnectCommandForm
,
UserListSearchForm
,
)
)
from
..models
import
Profile
,
GroupProfile
,
ConnectCommand
,
create_profile
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
from
.util
import
saml_available
,
DeleteViewBase
...
@@ -480,3 +486,46 @@ class ConnectCommandCreate(LoginRequiredMixin, SuccessMessageMixin,
...
@@ -480,3 +486,46 @@ class ConnectCommandCreate(LoginRequiredMixin, SuccessMessageMixin,
kwargs
=
super
(
ConnectCommandCreate
,
self
)
.
get_form_kwargs
()
kwargs
=
super
(
ConnectCommandCreate
,
self
)
.
get_form_kwargs
()
kwargs
[
'user'
]
=
self
.
request
.
user
kwargs
[
'user'
]
=
self
.
request
.
user
return
kwargs
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"
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment