mirror of https://github.com/jumpserver/jumpserver
User group detail
parent
8d358a7a68
commit
bd882c8bef
|
@ -297,6 +297,7 @@ jumpserver.initDataTable = function (options) {
|
||||||
url: options.i18n_url || "/static/js/plugins/dataTables/i18n/zh-hans.json"
|
url: options.i18n_url || "/static/js/plugins/dataTables/i18n/zh-hans.json"
|
||||||
},
|
},
|
||||||
order: options.order || [[ 1, 'asc' ]],
|
order: options.order || [[ 1, 'asc' ]],
|
||||||
|
select: options.select || 'multi',
|
||||||
buttons: options.buttons || [
|
buttons: options.buttons || [
|
||||||
{extend: 'excel',
|
{extend: 'excel',
|
||||||
exportOptions: {
|
exportOptions: {
|
||||||
|
@ -323,9 +324,6 @@ jumpserver.initDataTable = function (options) {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
columnDefs: columnDefs,
|
columnDefs: columnDefs,
|
||||||
// select: 'single',
|
|
||||||
// select: options.select || {style: 'single'},
|
|
||||||
// select: false,
|
|
||||||
ajax: {
|
ajax: {
|
||||||
url: options.ajax_url ,
|
url: options.ajax_url ,
|
||||||
dataSrc: ""
|
dataSrc: ""
|
||||||
|
@ -333,16 +331,16 @@ jumpserver.initDataTable = function (options) {
|
||||||
columns: options.columns || [],
|
columns: options.columns || [],
|
||||||
lengthMenu: [[15, 25, 50, -1], [15, 25, 50, "All"]]
|
lengthMenu: [[15, 25, 50, -1], [15, 25, 50, "All"]]
|
||||||
});
|
});
|
||||||
// table.on('select', function(e, dt, type, indexes) {
|
table.on('select', function(e, dt, type, indexes) {
|
||||||
// var $node = table[ type ]( indexes ).nodes().to$();
|
var $node = table[ type ]( indexes ).nodes().to$();
|
||||||
// $node.find('input.ipt_check').prop('checked', true);
|
$node.find('input.ipt_check').prop('checked', true);
|
||||||
// }).on('deselect', function(e, dt, type, indexes) {
|
}).on('deselect', function(e, dt, type, indexes) {
|
||||||
// var $node = table[ type ]( indexes ).nodes().to$();
|
var $node = table[ type ]( indexes ).nodes().to$();
|
||||||
// $node.find('input.ipt_check').prop('checked', false);
|
$node.find('input.ipt_check').prop('checked', false);
|
||||||
// }).on('draw', function(){
|
}).on('draw', function(){
|
||||||
// $('#op').html(options.op_html || '');
|
$('#op').html(options.op_html || '');
|
||||||
// $('#uc').html(options.uc_html || '');
|
$('#uc').html(options.uc_html || '');
|
||||||
// });
|
});
|
||||||
$('.ipt_check_all').on('click', function() {
|
$('.ipt_check_all').on('click', function() {
|
||||||
if (!jumpserver.checked) {
|
if (!jumpserver.checked) {
|
||||||
$(this).closest('table').find('.ipt_check').prop('checked', true);
|
$(this).closest('table').find('.ipt_check').prop('checked', true);
|
||||||
|
@ -354,5 +352,6 @@ jumpserver.initDataTable = function (options) {
|
||||||
table.rows().deselect();
|
table.rows().deselect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,9 +30,9 @@ class UserViewSet(BulkModelViewSet):
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
class UserAndGroupEditApi(generics.RetrieveUpdateAPIView):
|
class UserUpdateGroupApi(generics.RetrieveUpdateAPIView):
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all()
|
||||||
serializer_class = serializers.UserAndGroupSerializer
|
serializer_class = serializers.UserUpdateGroupSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,7 +72,17 @@ class UserUpdatePKApi(generics.UpdateAPIView):
|
||||||
user.public_key = serializer.validated_data['_public_key']
|
user.public_key = serializer.validated_data['_public_key']
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
#
|
|
||||||
|
class UserGroupViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = UserGroup.objects.all()
|
||||||
|
serializer_class = serializers.UserGroupSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupUpdateUserApi(generics.RetrieveUpdateAPIView):
|
||||||
|
queryset = UserGroup.objects.all()
|
||||||
|
serializer_class = serializers.UserGroupUpdateMemeberSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
# class GroupDetailApi(generics.RetrieveUpdateDestroyAPIView):
|
# class GroupDetailApi(generics.RetrieveUpdateDestroyAPIView):
|
||||||
# queryset = UserGroup.objects.all()
|
# queryset = UserGroup.objects.all()
|
||||||
# serializer_class = serializers.GroupDetailSerializer
|
# serializer_class = serializers.GroupDetailSerializer
|
||||||
|
|
|
@ -16,8 +16,7 @@ from .models import User, UserGroup
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
group_display = serializers.SerializerMethodField()
|
groups_display = serializers.SerializerMethodField()
|
||||||
active_display = serializers.SerializerMethodField()
|
|
||||||
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
|
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -27,17 +26,16 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super(UserSerializer, self).get_field_names(declared_fields, info)
|
fields = super(UserSerializer, self).get_field_names(declared_fields, info)
|
||||||
fields.extend(['group_display', 'get_role_display'])
|
fields.extend(['groups_display', 'get_role_display', 'is_valid'])
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_group_display(obj):
|
def get_groups_display(obj):
|
||||||
return " ".join([group.name for group in obj.groups.all()])
|
return " ".join([group.name for group in obj.groups.all()])
|
||||||
|
|
||||||
@staticmethod
|
# @staticmethod
|
||||||
def get_active_display(obj):
|
# def get_active_display(obj):
|
||||||
# TODO: user active state
|
# return not (obj.is_expired and obj.is_active)
|
||||||
return not (obj.is_expired and obj.is_active)
|
|
||||||
|
|
||||||
|
|
||||||
class UserPKUpdateSerializer(serializers.ModelSerializer):
|
class UserPKUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
@ -54,7 +52,7 @@ class UserPKUpdateSerializer(serializers.ModelSerializer):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class UserAndGroupSerializer(serializers.ModelSerializer):
|
class UserUpdateGroupSerializer(serializers.ModelSerializer):
|
||||||
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
|
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -62,6 +60,26 @@ class UserAndGroupSerializer(serializers.ModelSerializer):
|
||||||
fields = ['id', 'groups']
|
fields = ['id', 'groups']
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
|
user_amount = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = UserGroup
|
||||||
|
list_serializer_class = BulkListSerializer
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_user_amount(obj):
|
||||||
|
return obj.users.count()
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupUpdateMemeberSerializer(serializers.ModelSerializer):
|
||||||
|
users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = UserGroup
|
||||||
|
fields = ['id', 'users']
|
||||||
|
|
||||||
|
|
||||||
# class GroupDetailSerializer(serializers.ModelSerializer):
|
# class GroupDetailSerializer(serializers.ModelSerializer):
|
||||||
# class Meta:
|
# class Meta:
|
||||||
# model = UserGroup
|
# model = UserGroup
|
||||||
|
|
|
@ -224,9 +224,8 @@
|
||||||
jumpserver.selected_groups = {};
|
jumpserver.selected_groups = {};
|
||||||
|
|
||||||
function updateUserGroups(user_groups) {
|
function updateUserGroups(user_groups) {
|
||||||
var the_url = "{% url 'users:group-user-edit-api' pk=user.id %}";
|
var the_url = "{% url 'users:api-user-update-group' pk=user.id %}";
|
||||||
var body = {
|
var body = {
|
||||||
id: {{ user.id }},
|
|
||||||
groups: Object.assign([], user_groups)
|
groups: Object.assign([], user_groups)
|
||||||
};
|
};
|
||||||
var success = function(data) {
|
var success = function(data) {
|
||||||
|
@ -245,13 +244,11 @@ function updateUserGroups(user_groups) {
|
||||||
});
|
});
|
||||||
// clear jumpserver.selected_groups
|
// clear jumpserver.selected_groups
|
||||||
jumpserver.selected_groups = {};
|
jumpserver.selected_groups = {};
|
||||||
toastr.success('{% trans "UserGroup Update Success!" %}')
|
|
||||||
};
|
};
|
||||||
APIUpdateAttr({
|
APIUpdateAttr({
|
||||||
url: the_url,
|
url: the_url,
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
success: success,
|
success: success
|
||||||
method: 'PUT'
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
|
@ -11,52 +11,52 @@
|
||||||
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
||||||
<script src="{% static "js/plugins/dataTables/dataTables.min.js" %}"></script>
|
<script src="{% static "js/plugins/dataTables/dataTables.min.js" %}"></script>
|
||||||
<style>
|
<style>
|
||||||
.user_div {
|
.user_div {
|
||||||
color: #5e5e5e;
|
color: #5e5e5e;
|
||||||
font-family: "Open Sans";
|
font-family: "Open Sans";
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
.user_div .ui_container {
|
.user_div .ui_container {
|
||||||
background-color: #d1dade;
|
background-color: #d1dade;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.user_div a {
|
.user_div a {
|
||||||
color: #5e5e5e;
|
color: #5e5e5e;
|
||||||
}
|
}
|
||||||
.user_div .remove {
|
.user_div .remove {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
dl {
|
dl {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
border-bottom: 1px solid #e7eaec;
|
border-bottom: 1px solid #e7eaec;
|
||||||
}
|
}
|
||||||
dt {
|
dt {
|
||||||
float: left;
|
float: left;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0
|
margin: 0
|
||||||
}
|
}
|
||||||
dd {
|
dd {
|
||||||
float: left;
|
float: left;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0
|
margin: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#group_user_row dt {
|
#group_user_row dt {
|
||||||
border-bottom: 1px solid #e7eaec;
|
border-bottom: 1px solid #e7eaec;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#group_user_row dd {
|
#group_user_row dd {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -67,7 +67,7 @@ dd {
|
||||||
<div class="panel-options">
|
<div class="panel-options">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a href="{% url 'users:user-group-detail' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User Group Detail' %} </a>
|
<a href="{% url 'users:user-group-detail' pk=user_group.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User Group Detail' %} </a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,7 +75,7 @@ dd {
|
||||||
<div class="col-sm-7" style="padding-left: 0">
|
<div class="col-sm-7" style="padding-left: 0">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-title">
|
<div class="ibox-title">
|
||||||
<span class="label"><b>{{ object.name }}</b></span>
|
<span class="label"><b>{{ user_group.name }}</b></span>
|
||||||
<div class="ibox-tools">
|
<div class="ibox-tools">
|
||||||
<a class="collapse-link">
|
<a class="collapse-link">
|
||||||
<i class="fa fa-chevron-up"></i>
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
@ -86,53 +86,62 @@ dd {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<dl>
|
<table class="table">
|
||||||
<dt width="20%">{% trans 'Name' %}:</dt>
|
<tbody>
|
||||||
<dd><b>{{ object.name }}</b></dd>
|
<tr class="no-borders-tr">
|
||||||
</dl>
|
<td width="20%">{% trans 'Name' %}:</td>
|
||||||
<dl>
|
<td><b>{{ user_group.name }}</b></td>
|
||||||
<dt>{% trans 'Comment' %}:</dt>
|
</tr>
|
||||||
<dd><b>{{ object.comment }}</b></dd>
|
<tr>
|
||||||
</dl>
|
<td>{% trans 'Create by' %}:</td>
|
||||||
<dl>
|
<td><b>{{ user_group.created_by }}</b></td>
|
||||||
<dt>{% trans 'Created at' %}:</dt>
|
</tr>
|
||||||
<dd><b>{{ object.date_created }}</b></dd>
|
<tr>
|
||||||
</dl>
|
<td>{% trans 'Date created' %}:</td>
|
||||||
<dl id="group_user_row">
|
<td><b>{{ user_group.date_created }}</b></td>
|
||||||
<dt>{% trans 'Users' %}:</dt>
|
</tr>
|
||||||
<dd style="line-height: 2" id="group_user_container">
|
<tr>
|
||||||
{% for user in object.users.all %}
|
<td>{% trans 'Comment' %}:</td>
|
||||||
<div class="col-sm-4 user_div"><div class="ui_container row"><div class="col-xs-9"><a href="{{ user.get_absolute_url }}" title="{{ user.name }}" data-toggle="tooltip">{{ user.name|truncatechars:15 }}</a></div><div class="col-xs-3"><a data-uid="{{ user.id }}" class="btn_remove m-l-5"><i class="remove fa fa-times-circle"></i></a></div></div></div>
|
<td><b>{{ user_group.comment }}</b></td>
|
||||||
{% endfor %}
|
</tr>
|
||||||
</dd>
|
</tbody>
|
||||||
</dl>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-info">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
|
<i class="fa fa-info-circle"></i> {% trans 'User' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table">
|
<table class="table user_edit">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<form>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% trans 'Add User' %}:</td>
|
<td colspan="2" class="no-borders">
|
||||||
<td>
|
<select data-placeholder="{% trans 'Add user' %}" id="slct_groups" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
<span class="pull-right">
|
{% for user in users %}
|
||||||
<button type="button" class="btn btn-primary btn-xs" id="btn_group_add_user" style="width: 54px" data-toggle="modal" data-target="#select_user_modal">{% trans 'Add' %}</button>
|
<option value="{{ user.id }}" id="opt_{{ user.id }}">{{ user.name }}</option>
|
||||||
</span>
|
{% endfor %}
|
||||||
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% trans 'Delete' %}:</td>
|
<td colspan="2" class="no-borders">
|
||||||
<td>
|
<button type="button" class="btn btn-info btn-small" id="btn_add_user_group">{% trans 'Add' %}</button>
|
||||||
<span class="pull-right">
|
|
||||||
<button type="button" class="btn btn-danger btn-xs" id="btn_group_delete" style="width: 54px">{% trans 'Delete' %}</button>
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% for user in user_group.users.all %}
|
||||||
|
<tr>
|
||||||
|
<td ><b class="bdg_user" data-uid={{ user.id }}>{{ user.name }}</b></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger pull-right btn-xs btn_delete_user" type="button"><i class="fa fa-minus"></i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -147,35 +156,63 @@ dd {
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
$(document).on('click', '.btn_remove', function(){
|
jumpserver.selected_groups = {};
|
||||||
|
|
||||||
|
function updateGroupMember(users) {
|
||||||
|
var the_url = "{% url 'users:api-user-group-update-user' pk=user_group.id %}";
|
||||||
|
var body = {
|
||||||
|
groups: Object.assign([], users)
|
||||||
|
};
|
||||||
|
var success = function(data) {
|
||||||
|
// remove all the selected groups from select > option and rendered ul element;
|
||||||
|
$('.select2-selection__rendered').empty();
|
||||||
|
$('#slct_users').val('');
|
||||||
|
$.map(jumpserver.selected_groups, function(user_name, index) {
|
||||||
|
$('#opt_' + index).remove();
|
||||||
|
// change tr html of users
|
||||||
|
$('.user_edit tbody').append(
|
||||||
|
'<tr>' +
|
||||||
|
'<td><b class="bdg_user" data-uid="' + index + '">' + user_name + '</b></td>' +
|
||||||
|
'<td><button class="btn btn-danger btn-xs pull-right btn_delete_user" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||||
|
'</tr>'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
// clear jumpserver.selected_groups
|
||||||
|
jumpserver.selected_users = {};
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
success: success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2();
|
||||||
|
}).on('click', '.btn_remove', function(){
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
var uid = $this.data('uid');
|
var uid = $this.data('uid');
|
||||||
var the_url = '{% url "users:delete-user-from-group-api" pk=object.id uid=99991937 %}'.replace('99991937', uid);
|
var the_url = '{% url "users:api-user-group-detail" pk=user_group.id %}'.replace('99991937', uid);
|
||||||
var success = function(){
|
var success = function(){
|
||||||
$this.closest('.user_div').remove();
|
$this.closest('.user_div').remove();
|
||||||
};
|
};
|
||||||
var error = function(){};
|
var error = function(){};
|
||||||
APIUpdateAttr({url: the_url, body: "{}", method: "DELETE", success: success, error: error});
|
APIUpdateAttr({url: the_url, body: "{}", method: "DELETE", success: success, error: error});
|
||||||
return false;
|
return false;
|
||||||
}).on('click', '#btn_group_delete', function() {
|
}).on('click', '.btn_delete_user', function() {
|
||||||
function doDelete() {
|
var $this = $(this);
|
||||||
var the_url = '{% url "users:user-group-detail-api" pk=object.id %}';
|
var $tr = $this.closest('tr');
|
||||||
var success = function() {
|
var $badge = $tr.find('.bdg_user_group');
|
||||||
window.location.href = '{% url "users:user-group-list" %}';
|
var gid = $badge.data('gid');
|
||||||
};
|
var group_name = $badge.html() || $badge.text();
|
||||||
APIUpdateAttr({url: the_url, body: "{}", method: "DELETE", success: success});
|
$('#slct_groups').append(
|
||||||
}
|
'<option value="' + gid + '" id="opt_' + gid + '">' + group_name + '</option>'
|
||||||
swal({
|
);
|
||||||
title: "{% trans 'Are you sure?' %}",
|
$tr.remove();
|
||||||
text: "{% trans 'This will delete the current group, but will not delete any user of it.' %}",
|
var user_groups = $('.bdg_user_group').map(function() {
|
||||||
type: "warning",
|
return $(this).data('gid');
|
||||||
showCancelButton: true,
|
}).get();
|
||||||
confirmButtonColor: "#DD6B55",
|
updateUserGroups(user_groups)
|
||||||
confirmButtonText: "{% trans 'Confirm' %}",
|
|
||||||
closeOnConfirm: false
|
|
||||||
}, function() {
|
|
||||||
doDelete();
|
|
||||||
});
|
|
||||||
}).on('shown.bs.modal', '#select_user_modal', function() {
|
}).on('shown.bs.modal', '#select_user_modal', function() {
|
||||||
if ($.fn.dataTable.isDataTable('#select_user_table')) {
|
if ($.fn.dataTable.isDataTable('#select_user_table')) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -197,7 +234,7 @@ $(document).on('click', '.btn_remove', function(){
|
||||||
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
|
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
ajax_url: '{% url "users:user-bulk-update-api" %}',
|
ajax_url: '{% url "users:api-user-list" %}',
|
||||||
columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" }, {data: "group_display" },
|
columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" }, {data: "group_display" },
|
||||||
{data: function(){return 999}}, {data: "active_display" }],
|
{data: function(){return 999}}, {data: "active_display" }],
|
||||||
};
|
};
|
||||||
|
@ -214,11 +251,11 @@ $(document).on('click', '.btn_remove', function(){
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
var body = {
|
var body = {
|
||||||
id: {{ object.id }},
|
id: {{ user_group.id }},
|
||||||
users: plain_id_list.map(Number)
|
users: plain_id_list.map(Number)
|
||||||
};
|
};
|
||||||
$('#select_user_modal').modal('hide');
|
$('#select_user_modal').modal('hide');
|
||||||
var the_url = "{% url 'users:user-group-detail-api' pk=object.id %}";
|
var the_url = "{% url 'users:api-user-group-detail' pk=user_group.id %}";
|
||||||
var success = function() {
|
var success = function() {
|
||||||
toastr.success('{% trans "The selected users has been added to current group." %}');
|
toastr.success('{% trans "The selected users has been added to current group." %}');
|
||||||
var html = "";
|
var html = "";
|
||||||
|
@ -236,7 +273,7 @@ $(document).on('click', '.btn_remove', function(){
|
||||||
].join("");
|
].join("");
|
||||||
});
|
});
|
||||||
$(html).appendTo($('#group_user_container'));
|
$(html).appendTo($('#group_user_container'));
|
||||||
}
|
};
|
||||||
APIUpdateAttr({url: the_url, body: JSON.stringify(body), success: success});
|
APIUpdateAttr({url: the_url, body: JSON.stringify(body), success: success});
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
<th class="text-center">{% trans 'Name' %}</th>
|
||||||
<th class="text-center">{% trans 'User Amount' %}</th>
|
<th class="text-center">{% trans 'User Amount' %}</th>
|
||||||
<th class="text-center">{% trans 'Asset Amount' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Comment' %}</th>
|
<th class="text-center">{% trans 'Comment' %}</th>
|
||||||
<th class="text-center">{% trans 'Action' %}</th>
|
<th class="text-center">{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -43,11 +42,11 @@ $(document).ready(function() {
|
||||||
var detail_btn = '<a href="{% url "users:user-group-detail" pk=99991937 %}">' + cellData + '</a>';
|
var detail_btn = '<a href="{% url "users:user-group-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
{targets: 3, createdCell: function (td, cellData) {
|
||||||
var innerHtml = cellData.length > 18 ? cellData.substring(0, 18) + '...': cellData;
|
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
|
||||||
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
|
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData, rowData) {
|
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||||
var update_btn = '<a href="{% url "users:user-group-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
var update_btn = '<a href="{% url "users:user-group-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_delete_user_group" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_delete_user_group" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||||
if (rowData.id === 1) {
|
if (rowData.id === 1) {
|
||||||
|
@ -56,9 +55,9 @@ $(document).ready(function() {
|
||||||
$(td).html(update_btn + del_btn)
|
$(td).html(update_btn + del_btn)
|
||||||
}
|
}
|
||||||
}}],
|
}}],
|
||||||
ajax_url: '{% url "users:user-group-bulk-update-api" %}',
|
ajax_url: '{% url "users:api-user-group-list" %}',
|
||||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "user_amount"},
|
columns: [{data: function(){return ""}}, {data: "name" }, {data: "user_amount"},
|
||||||
{data: function(){return 999}}, {data: "comment"}, {data: "id" }],
|
{data: "comment"}, {data: "id" }],
|
||||||
op_html: $('#actions').html()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
@ -66,7 +65,7 @@ $(document).ready(function() {
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
function doDelete() {
|
function doDelete() {
|
||||||
var group_id = $this.data('gid');
|
var group_id = $this.data('gid');
|
||||||
var the_url = "{% url 'users:user-group-detail-api' 99991937 %}".replace('99991937', group_id);
|
var the_url = "{% url 'users:api-user-group-detail' pk=99991937 %}".replace('99991937', group_id);
|
||||||
var body = {};
|
var body = {};
|
||||||
var success = function() {
|
var success = function() {
|
||||||
var msg = "{% trans 'Group Deleted.' %}";
|
var msg = "{% trans 'Group Deleted.' %}";
|
||||||
|
@ -76,7 +75,7 @@ $(document).ready(function() {
|
||||||
var fail = function() {
|
var fail = function() {
|
||||||
var msg = "{% trans 'Group Deleting failed.' %}";
|
var msg = "{% trans 'Group Deleting failed.' %}";
|
||||||
swal("{% trans 'Group Delete' %}", msg, "error");
|
swal("{% trans 'Group Delete' %}", msg, "error");
|
||||||
}
|
};
|
||||||
APIUpdateAttr({
|
APIUpdateAttr({
|
||||||
url: the_url,
|
url: the_url,
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
@ -105,8 +104,8 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
if (plain_id_list === []) {
|
if (plain_id_list === []) {
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
var the_url = "{% url 'users:user-group-bulk-update-api' %}";
|
var the_url = "{% url 'users:api-user-group-list' %}";
|
||||||
function doDelete() {
|
function doDelete() {
|
||||||
swal({
|
swal({
|
||||||
title: "{% trans 'Are you sure?' %}",
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
<th class="text-center">{% trans 'Username' %}</th>
|
<th class="text-center">{% trans 'Username' %}</th>
|
||||||
<th class="text-center">{% trans 'Role' %}</th>
|
<th class="text-center">{% trans 'Role' %}</th>
|
||||||
<th class="text-center">{% trans 'User group' %}</th>
|
<th class="text-center">{% trans 'User group' %}</th>
|
||||||
<th class="text-center">{% trans 'Asset num' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Active' %}</th>
|
<th class="text-center">{% trans 'Active' %}</th>
|
||||||
<th class="text-center">{% trans 'Action' %}</th>
|
<th class="text-center">{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -56,14 +55,14 @@ $(document).ready(function(){
|
||||||
var innerHtml = cellData.length > 20 ? cellData.substring(0, 20) + '...': cellData;
|
var innerHtml = cellData.length > 20 ? cellData.substring(0, 20) + '...': cellData;
|
||||||
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
||||||
}},
|
}},
|
||||||
{targets: 6, createdCell: function (td, cellData) {
|
{targets: 5, createdCell: function (td, cellData) {
|
||||||
if (!cellData) {
|
if (!cellData) {
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
} else {
|
} else {
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 7, createdCell: function (td, cellData, rowData) {
|
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||||
var update_btn = '<a href="{% url "users:user-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
var update_btn = '<a href="{% url "users:user-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||||
if (rowData.id === 1 || rowData.username == "admin") {
|
if (rowData.id === 1 || rowData.username == "admin") {
|
||||||
|
@ -73,8 +72,8 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
}}],
|
}}],
|
||||||
ajax_url: '{% url "users:api-user-list" %}',
|
ajax_url: '{% url "users:api-user-list" %}',
|
||||||
columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" }, {data: "group_display" },
|
columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" },
|
||||||
{data: function(){return 999}}, {data: "active_display" }, {data: "id" }],
|
{data: "groups_display" }, {data: "is_valid" }, {data: "id" }],
|
||||||
op_html: $('#actions').html()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
@ -224,6 +223,8 @@ $(document).ready(function(){
|
||||||
$form.ajaxSubmit({success: success});
|
$form.ajaxSubmit({success: success});
|
||||||
}).on('change', '#id_excel', function() {
|
}).on('change', '#id_excel', function() {
|
||||||
$(this).siblings('.help-block').remove();
|
$(this).siblings('.help-block').remove();
|
||||||
|
}).on('click', '.ipt_check', function () {
|
||||||
|
console.log('Hello')
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -39,6 +39,7 @@ urlpatterns = [
|
||||||
|
|
||||||
router = BulkRouter()
|
router = BulkRouter()
|
||||||
router.register(r'v1/users', api.UserViewSet, 'api-user')
|
router.register(r'v1/users', api.UserViewSet, 'api-user')
|
||||||
|
router.register(r'v1/user-groups', api.UserGroupViewSet, 'api-user-group')
|
||||||
# router.register(r'v1/user-groups', api.AssetViewSet, 'api-groups')
|
# router.register(r'v1/user-groups', api.AssetViewSet, 'api-groups')
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +54,9 @@ urlpatterns += [
|
||||||
# url(r'^v1/user-groups/(?P<pk>\d+)/user/(?P<uid>\d+)/$',
|
# url(r'^v1/user-groups/(?P<pk>\d+)/user/(?P<uid>\d+)/$',
|
||||||
# api.DeleteUserFromGroupApi.as_view(), name='delete-user-from-group-api'),
|
# api.DeleteUserFromGroupApi.as_view(), name='delete-user-from-group-api'),
|
||||||
url(r'^v1/users/(?P<pk>\d+)/groups/$',
|
url(r'^v1/users/(?P<pk>\d+)/groups/$',
|
||||||
api.UserAndGroupEditApi.as_view(), name='group-user-edit-api'),
|
api.UserUpdateGroupApi.as_view(), name='api-user-update-group'),
|
||||||
|
url(r'^v1/user-groups/(?P<pk>\d+)/users/$',
|
||||||
|
api.UserGroupUpdateUserApi.as_view(), name='api-user-group-update-user'),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += router.urls
|
urlpatterns += router.urls
|
||||||
|
|
|
@ -216,10 +216,16 @@ class UserGroupUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||||
|
|
||||||
class UserGroupDetailView(AdminUserRequiredMixin, DetailView):
|
class UserGroupDetailView(AdminUserRequiredMixin, DetailView):
|
||||||
model = UserGroup
|
model = UserGroup
|
||||||
|
context_object_name = 'user_group'
|
||||||
template_name = 'users/user_group_detail.html'
|
template_name = 'users/user_group_detail.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {'app': _('Users'), 'action': _('User Group Detail')}
|
users = User.objects.exclude(id__in=self.object.users.all())
|
||||||
|
context = {
|
||||||
|
'app': _('Users'),
|
||||||
|
'action': _('User Group Detail'),
|
||||||
|
'users': users,
|
||||||
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
return super(UserGroupDetailView, self).get_context_data(**kwargs)
|
return super(UserGroupDetailView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue