Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
556fb4e0
Commit
556fb4e0
authored
Sep 06, 2016
by
xiaokong1937@gmail.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor `is_active` trigger view and `enable_otp` trigger view in UserDetail page;trivial changes
parent
a3096689
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
330 additions
and
119 deletions
+330
-119
toastr.min.css
apps/static/css/plugins/toastr/toastr.min.css
+223
-0
jumpserver.js
apps/static/js/jumpserver.js
+22
-2
_foot_js.html
apps/templates/_foot_js.html
+39
-40
_head_css_js.html
apps/templates/_head_css_js.html
+1
-0
api.py
apps/users/api.py
+1
-11
serializers.py
apps/users/serializers.py
+0
-7
user_detail.html
apps/users/templates/users/user_detail.html
+42
-56
urls.py
apps/users/urls.py
+0
-1
views.py
apps/users/views.py
+2
-2
No files found.
apps/static/css/plugins/toastr/toastr.min.css
0 → 100644
View file @
556fb4e0
.toast-title
{
font-weight
:
700
}
.toast-message
{
-ms-word-wrap
:
break-word
;
word-wrap
:
break-word
}
.toast-message
a
,
.toast-message
label
{
color
:
#fff
}
.toast-message
a
:hover
{
color
:
#ccc
;
text-decoration
:
none
}
.toast-close-button
{
position
:
relative
;
right
:
-.3em
;
top
:
-.3em
;
float
:
right
;
font-size
:
20px
;
font-weight
:
700
;
color
:
#fff
;
-webkit-text-shadow
:
0
1px
0
#fff
;
text-shadow
:
0
1px
0
#fff
;
opacity
:
.8
;
-ms-filter
:
alpha
(
Opacity
=
80
);
filter
:
alpha
(
opacity
=
80
)
}
.toast-close-button
:focus
,
.toast-close-button
:hover
{
color
:
#000
;
text-decoration
:
none
;
cursor
:
pointer
;
opacity
:
.4
;
-ms-filter
:
alpha
(
Opacity
=
40
);
filter
:
alpha
(
opacity
=
40
)
}
button
.toast-close-button
{
padding
:
0
;
cursor
:
pointer
;
background
:
0
0
;
border
:
0
;
-webkit-appearance
:
none
}
.toast-top-center
{
top
:
0
;
right
:
0
;
width
:
100%
}
.toast-bottom-center
{
bottom
:
0
;
right
:
0
;
width
:
100%
}
.toast-top-full-width
{
top
:
0
;
right
:
0
;
width
:
100%
}
.toast-bottom-full-width
{
bottom
:
0
;
right
:
0
;
width
:
100%
}
.toast-top-left
{
top
:
12px
;
left
:
12px
}
.toast-top-right
{
top
:
12px
;
right
:
12px
}
.toast-bottom-right
{
right
:
12px
;
bottom
:
12px
}
.toast-bottom-left
{
bottom
:
12px
;
left
:
12px
}
#toast-container
{
position
:
fixed
;
z-index
:
999999
}
#toast-container
*
{
-moz-box-sizing
:
border-box
;
-webkit-box-sizing
:
border-box
;
box-sizing
:
border-box
}
#toast-container
>
div
{
position
:
relative
;
overflow
:
hidden
;
margin
:
0
0
6px
;
padding
:
15px
15px
15px
50px
;
width
:
300px
;
-moz-border-radius
:
3px
;
-webkit-border-radius
:
3px
;
border-radius
:
3px
;
background-position
:
15px
center
;
background-repeat
:
no-repeat
;
-moz-box-shadow
:
0
0
12px
#999
;
-webkit-box-shadow
:
0
0
12px
#999
;
box-shadow
:
0
0
12px
#999
;
color
:
#fff
;
opacity
:
.8
;
-ms-filter
:
alpha
(
Opacity
=
80
);
filter
:
alpha
(
opacity
=
80
)
}
#toast-container
>
:hover
{
-moz-box-shadow
:
0
0
12px
#000
;
-webkit-box-shadow
:
0
0
12px
#000
;
box-shadow
:
0
0
12px
#000
;
opacity
:
1
;
-ms-filter
:
alpha
(
Opacity
=
100
);
filter
:
alpha
(
opacity
=
100
);
cursor
:
pointer
}
#toast-container
>
.toast-info
{
background-image
:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)
!important
}
#toast-container
>
.toast-error
{
background-image
:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)
!important
}
#toast-container
>
.toast-success
{
background-image
:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)
!important
}
#toast-container
>
.toast-warning
{
background-image
:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)
!important
}
#toast-container
.toast-bottom-center
>
div
,
#toast-container
.toast-top-center
>
div
{
width
:
300px
;
margin
:
auto
}
#toast-container
.toast-bottom-full-width
>
div
,
#toast-container
.toast-top-full-width
>
div
{
width
:
96%
;
margin
:
auto
}
.toast
{
background-color
:
#030303
}
.toast-success
{
background-color
:
#51a351
}
.toast-error
{
background-color
:
#bd362f
}
.toast-info
{
background-color
:
#2f96b4
}
.toast-warning
{
background-color
:
#f89406
}
.toast-progress
{
position
:
absolute
;
left
:
0
;
bottom
:
0
;
height
:
4px
;
background-color
:
#000
;
opacity
:
.4
;
-ms-filter
:
alpha
(
Opacity
=
40
);
filter
:
alpha
(
opacity
=
40
)
}
@media
all
and
(
max-width
:
240px
)
{
#toast-container
>
div
{
padding
:
8px
8px
8px
50px
;
width
:
11em
}
#toast-container
.toast-close-button
{
right
:
-.2em
;
top
:
-.2em
}
}
@media
all
and
(
min-width
:
241px
)
and
(
max-width
:
480px
)
{
#toast-container
>
div
{
padding
:
8px
8px
8px
50px
;
width
:
18em
}
#toast-container
.toast-close-button
{
right
:
-.2em
;
top
:
-.2em
}
}
@media
all
and
(
min-width
:
481px
)
and
(
max-width
:
768px
)
{
#toast-container
>
div
{
padding
:
15px
15px
15px
50px
;
width
:
25em
}
}
\ No newline at end of file
apps/static/js/jumpserver.js
View file @
556fb4e0
...
...
@@ -151,4 +151,25 @@ function getIDall() {
check_array
.
push
(
id
);
});
return
check_array
.
join
(
","
);
}
\ No newline at end of file
}
function
APIUpdateAttr
(
url
,
body
,
success
,
error
,
method
)
{
$
.
ajax
({
url
:
url
,
type
:
method
||
"PATCH"
,
data
:
body
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
if
(
typeof
success
===
'function'
)
{
return
success
(
data
)
}
else
{
toastr
.
success
(
'Update Success!'
)
}
}).
fail
(
function
(
jqXHR
,
textStatue
,
errorThrown
)
{
if
(
typeof
error
===
'function'
)
{
return
error
(
errorThrown
)
}
else
{
toastr
.
error
(
'Error occurred while updating.'
)
}
})
return
true
;
}
apps/templates/_foot_js.html
View file @
556fb4e0
{% load static %}
<!-- Mainly scripts -->
<script
src=
"{% static "
js
/
plugins
/
metisMenu
/
jquery
.
metisMenu
.
js
"
%}"
></script>
<script
src=
"{% static "
js
/
plugins
/
toastr
/
toastr
.
min
.
js
"
%}"
></script>
<!-- Custom and plugin javascript -->
<script
src=
"{% static "
js
/
plugins
/
toastr
/
toastr
.
min
.
js
"
%}"
></script>
<script
src=
"{% static "
js
/
inspinia
.
js
"
%}"
></script>
<script
src=
"{% static "
js
/
jumpserver
.
js
"
%}"
></script>
<script>
// active menu
var
url_array
=
document
.
location
.
pathname
.
split
(
"/"
);
app
=
url_array
[
1
];
resource
=
url_array
[
2
];
if
(
app
==
''
){
$
(
'#index'
).
addClass
(
'active'
)
}
else
{
$
(
"#"
+
app
).
addClass
(
'active'
);
$
(
'#'
+
app
+
' #'
+
resource
).
addClass
(
'active'
);
}
// active menu
var
url_array
=
document
.
location
.
pathname
.
split
(
"/"
);
app
=
url_array
[
1
];
resource
=
url_array
[
2
];
if
(
app
==
''
){
$
(
'#index'
).
addClass
(
'active'
)
}
else
{
$
(
"#"
+
app
).
addClass
(
'active'
);
$
(
'#'
+
app
+
' #'
+
resource
).
addClass
(
'active'
);
}
// ajax set cookie
function
getCookie
(
name
)
{
var
cookieValue
=
null
;
if
(
document
.
cookie
&&
document
.
cookie
!==
''
)
{
var
cookies
=
document
.
cookie
.
split
(
';'
);
for
(
var
i
=
0
;
i
<
cookies
.
length
;
i
++
)
{
var
cookie
=
jQuery
.
trim
(
cookies
[
i
]);
// Does this cookie string begin with the name we want?
if
(
cookie
.
substring
(
0
,
name
.
length
+
1
)
===
(
name
+
'='
))
{
cookieValue
=
decodeURIComponent
(
cookie
.
substring
(
name
.
length
+
1
));
break
;
}
// ajax set cookie
function
getCookie
(
name
)
{
var
cookieValue
=
null
;
if
(
document
.
cookie
&&
document
.
cookie
!==
''
)
{
var
cookies
=
document
.
cookie
.
split
(
';'
);
for
(
var
i
=
0
;
i
<
cookies
.
length
;
i
++
)
{
var
cookie
=
jQuery
.
trim
(
cookies
[
i
]);
// Does this cookie string begin with the name we want?
if
(
cookie
.
substring
(
0
,
name
.
length
+
1
)
===
(
name
+
'='
))
{
cookieValue
=
decodeURIComponent
(
cookie
.
substring
(
name
.
length
+
1
));
break
;
}
}
return
cookieValue
;
}
return
cookieValue
;
}
var
csrftoken
=
getCookie
(
'csrftoken'
);
var
sessionid
=
getCookie
(
'sessionid'
);
var
csrftoken
=
getCookie
(
'csrftoken'
);
var
sessionid
=
getCookie
(
'sessionid'
);
function
csrfSafeMethod
(
method
)
{
// these HTTP methods do not require CSRF protection
return
(
/^
(
GET|HEAD|OPTIONS|TRACE
)
$/
.
test
(
method
));
}
function
csrfSafeMethod
(
method
)
{
// these HTTP methods do not require CSRF protection
return
(
/^
(
GET|HEAD|OPTIONS|TRACE
)
$/
.
test
(
method
));
}
$
.
ajaxSetup
({
beforeSend
:
function
(
xhr
,
settings
)
{
if
(
!
csrfSafeMethod
(
settings
.
type
)
&&
!
this
.
crossDomain
)
{
xhr
.
setRequestHeader
(
"X-CSRFToken"
,
csrftoken
);
}
$
.
ajaxSetup
({
beforeSend
:
function
(
xhr
,
settings
)
{
if
(
!
csrfSafeMethod
(
settings
.
type
)
&&
!
this
.
crossDomain
)
{
xhr
.
setRequestHeader
(
"X-CSRFToken"
,
csrftoken
);
}
});
}
});
// textarea rows
$
(
'textarea'
).
attr
(
'rows'
,
5
)
// textarea rows
$
(
'textarea'
).
attr
(
'rows'
,
5
)
</script>
<script
src=
"{% static "
js
/
jumpserver
.
js
"
%}"
></script>
apps/templates/_head_css_js.html
View file @
556fb4e0
...
...
@@ -3,6 +3,7 @@
<!-- css file -->
<link
href=
"{% static "
css
/
bootstrap
.
min
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
font-awesome
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
plugins
/
toastr
/
toastr
.
min
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
style
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
plugins
/
vaildator
/
jquery
.
validator
.
css
"
%}"
rel=
"stylesheet"
>
...
...
apps/users/api.py
View file @
556fb4e0
...
...
@@ -5,7 +5,7 @@ import logging
from
rest_framework
import
generics
from
.serializers
import
UserSerializer
,
UserGroupSerializer
,
UserA
ctiveSerializer
,
UserA
ttributeSerializer
from
.serializers
import
UserSerializer
,
UserGroupSerializer
,
UserAttributeSerializer
from
.models
import
User
,
UserGroup
...
...
@@ -31,16 +31,6 @@ class UserDetailDeleteUpdateApi(generics.RetrieveUpdateDestroyAPIView):
# return super(UserDetailDeleteUpdateApi, self).get(request, *args, **kwargs)
class
UserActiveApi
(
generics
.
RetrieveUpdateDestroyAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserActiveSerializer
# def put(self, request, *args, **kwargs):
# for k, v in request.META.items():
# logger.debug("%s --> %s" % (k, v))
# return super(UserActiveApi, self).put(request, *args, **kwargs)
class
UserGroupListAddApi
(
generics
.
ListCreateAPIView
):
queryset
=
UserGroup
.
objects
.
all
()
serializer_class
=
UserGroupSerializer
...
...
apps/users/serializers.py
View file @
556fb4e0
...
...
@@ -17,13 +17,6 @@ class UserSerializer(serializers.ModelSerializer):
]
class
UserActiveSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
User
fields
=
[
'is_active'
]
class
UserGroupSerializer
(
serializers
.
ModelSerializer
):
users
=
serializers
.
HyperlinkedRelatedField
(
many
=
True
,
read_only
=
True
,
view_name
=
'users:user-detail-api'
)
...
...
apps/users/templates/users/user_detail.html
View file @
556fb4e0
...
...
@@ -38,7 +38,7 @@
<div
class=
"col-sm-7"
style=
"padding-left: 0px;"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label"
><b>
{{ user.name }}
</b></span>
<span
class=
"label"
><b>
{{ user
_object
.name }}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -62,56 +62,56 @@
<tbody>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"2"
>
<img
src=
"{{ user | user_avatar_url }}"
class=
"img-circle"
width=
"64"
height=
"64"
>
<img
src=
"{{ user
_object
| user_avatar_url }}"
class=
"img-circle"
width=
"64"
height=
"64"
>
</td>
</tr>
<tr>
<td
width=
"20%"
>
{% trans 'Name' %}:
</td>
<td><b>
{{ user.name }}
</b></td>
<td><b>
{{ user
_object
.name }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Username' %}:
</td>
<td><b>
{{ user.username }}
</b></td>
<td><b>
{{ user
_object
.username }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Email' %}:
</td>
<td><b>
{{ user.email }}
</b></td>
<td><b>
{{ user
_object
.email }}
</b></td>
</tr>
{% if user.phone %}
{% if user
_object
.phone %}
<tr>
<td>
{% trans 'Phone' %}:
</td>
<td><b>
{{ user.phone }}
</b></td>
<td><b>
{{ user
_object
.phone }}
</b></td>
</tr>
{% endif %}
{% if user.wechat %}
{% if user
_object
.wechat %}
<tr>
<td>
{% trans 'Wechat' %}:
</td>
<td><b>
{{ user.wechat }}
</b></td>
<td><b>
{{ user
_object
.wechat }}
</b></td>
</tr>
{% endif %}
<tr>
<td>
{% trans 'Role' %}:
</td>
<td><b>
{{ user.get_role_display }}
</b></td>
<td><b>
{{ user
_object
.get_role_display }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Date expired' %}:
</td>
<td><b>
{{ user.date_expired|date:"Y-m-j H:i:s" }}
</b></td>
<td><b>
{{ user
_object
.date_expired|date:"Y-m-j H:i:s" }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Created by' %}:
</td>
<td><b>
{{ user.created_by }}
</b></td>
<td><b>
{{ user
_object
.created_by }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Date joined' %}:
</td>
<td><b>
{{ user.date_joined|date:"Y-m-j H:i:s" }}
</b></td>
<td><b>
{{ user
_object
.date_joined|date:"Y-m-j H:i:s" }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Last login' %}:
</td>
<td><b>
{{ user.last_login|date:"Y-m-j H:i:s" }}
</b></td>
<td><b>
{{ user
_object
.last_login|date:"Y-m-j H:i:s" }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Comment' %}:
</td>
<td><b>
{{ user.comment }}
</b></td>
<td><b>
{{ user
_object
.comment }}
</b></td>
</tr>
</tbody>
</table>
...
...
@@ -131,7 +131,7 @@
<td><span
style=
"float: right"
>
<div
class=
"switch"
>
<div
class=
"onoffswitch"
>
<input
type=
"checkbox"
{%
if
user
.
is_active
%}
checked
{%
endif
%}
class=
"onoffswitch-checkbox"
id=
"is_active"
onchange=
"switch_user_status(this)
"
>
<input
type=
"checkbox"
{%
if
user
_object
.
is_active
%}
checked
{%
endif
%}
class=
"onoffswitch-checkbox"
id=
"is_active
"
>
<label
class=
"onoffswitch-label"
for=
"is_active"
>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-switch"
></span>
...
...
@@ -145,9 +145,9 @@
<td><span
style=
"float: right"
>
<div
class=
"switch"
>
<div
class=
"onoffswitch"
>
<input
type=
"checkbox"
class=
"onoffswitch-checkbox"
id=
"e
xample2
"
>
<label
class=
"onoffswitch-label"
for=
"e
xample2
"
>
<input
type=
"checkbox"
class=
"onoffswitch-checkbox"
{%
if
user_object
.
enable_otp
%}
checked
{%
endif
%}
id=
"e
nable_otp
"
>
<label
class=
"onoffswitch-label"
for=
"e
nable_otp
"
>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-switch"
></span>
</label>
...
...
@@ -200,7 +200,7 @@
</tr>
</form>
{% for group in user.groups.all %}
{% for group in user
_object
.groups.all %}
<tr>
<td
><b>
{{ group.name }}
</b></td>
<td>
...
...
@@ -222,40 +222,26 @@
{% endblock %}
{% block custom_foot_js %}
<script>
function
api_update_attr
(
url
,
body
,
method
,
success
,
error
)
{
$
.
ajax
({
url
:
url
,
type
:
method
||
"PATCH"
,
data
:
body
}).
done
(
function
(
data
)
{
if
(
typeof
success
====
'function'
)
{
return
success
(
data
)
}
else
{
}
})
}
function
switch_user_status
(
obj
)
{
var
status
=
$
(
obj
).
prop
(
'checked'
);
$
.
ajax
({
url
:
"{% url 'users:user-active-api' pk=user.id %}"
,
type
:
"PUT"
,
data
:
{
'is_active'
:
status
},
success
:
function
(
data
,
status
)
{
console
.
log
(
data
)
},
error
:
function
()
{
console
.
log
(
'error'
)
}
})
}
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
();
})
</script>
<script>
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
();
});
$
(
document
).
on
(
'click'
,
'#is_active'
,
function
(){
var
the_url
=
"{% url 'users:user-patch-api' pk=user_object.id %}"
;
var
checked
=
!
$
(
this
).
prop
(
'checked'
);
var
body
=
{
'is_active'
:
checked
};
var
success
=
function
(
data
)
{
toastr
.
success
(
'{% trans "Update success!" %}'
)
}
APIUpdateAttr
(
the_url
,
body
,
success
);
}).
on
(
'click'
,
'#enable_otp'
,
function
(){
var
the_url
=
"{% url 'users:user-patch-api' pk=user_object.id %}"
;
var
checked
=
!
$
(
this
).
prop
(
'checked'
);
var
body
=
{
'enable_otp'
:
checked
};
var
success
=
function
(
data
)
{
toastr
.
success
(
'{% trans "Update success!" %}'
)
}
APIUpdateAttr
(
the_url
,
body
,
success
);
});
</script>
{% endblock %}
apps/users/urls.py
View file @
556fb4e0
...
...
@@ -33,7 +33,6 @@ urlpatterns += [
api
.
UserDetailDeleteUpdateApi
.
as_view
(),
name
=
'user-detail-api'
),
url
(
r'^v1/users/(?P<pk>[0-9]+)/patch$'
,
api
.
UserAttributeApi
.
as_view
(),
name
=
'user-patch-api'
),
url
(
r'^v1/users/(?P<pk>[0-9]+)/active$'
,
api
.
UserActiveApi
.
as_view
(),
name
=
'user-active-api'
),
url
(
r'^v1/user-groups$'
,
api
.
UserGroupListAddApi
.
as_view
(),
name
=
'user-group-list-api'
),
url
(
r'^v1/user-groups/(?P<pk>[0-9]+)$'
,
api
.
UserGroupDetailDeleteUpdateApi
.
as_view
(),
name
=
'user-group-detail-api'
),
...
...
apps/users/views.py
View file @
556fb4e0
...
...
@@ -155,10 +155,10 @@ class UserDeleteView(AdminUserRequiredMixin, DeleteView):
class
UserDetailView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
User
template_name
=
'users/user_detail.html'
context_object_name
=
"user"
context_object_name
=
"user
_object
"
def
get_context_data
(
self
,
**
kwargs
):
groups
=
[
group
for
group
in
UserGroup
.
objects
.
iterator
()
if
group
not
in
self
.
object
.
groups
.
iterator
()]
groups
=
UserGroup
.
objects
.
exclude
(
id__in
=
self
.
object
.
groups
.
all
())
context
=
{
'app'
:
_
(
'Users'
),
'action'
:
_
(
'User detail'
),
'groups'
:
groups
}
kwargs
.
update
(
context
)
return
super
(
UserDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
...
...
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