diff --git a/apps/static/js/jumpserver.js b/apps/static/js/jumpserver.js
index 367e51d05..a4c8930b6 100644
--- a/apps/static/js/jumpserver.js
+++ b/apps/static/js/jumpserver.js
@@ -297,6 +297,7 @@ jumpserver.initDataTable = function (options) {
url: options.i18n_url || "/static/js/plugins/dataTables/i18n/zh-hans.json"
},
order: options.order || [[ 1, 'asc' ]],
+ select: options.select || 'multi',
buttons: options.buttons || [
{extend: 'excel',
exportOptions: {
@@ -323,9 +324,6 @@ jumpserver.initDataTable = function (options) {
}
],
columnDefs: columnDefs,
- // select: 'single',
- // select: options.select || {style: 'single'},
- // select: false,
ajax: {
url: options.ajax_url ,
dataSrc: ""
@@ -333,16 +331,16 @@ jumpserver.initDataTable = function (options) {
columns: options.columns || [],
lengthMenu: [[15, 25, 50, -1], [15, 25, 50, "All"]]
});
- // table.on('select', function(e, dt, type, indexes) {
- // var $node = table[ type ]( indexes ).nodes().to$();
- // $node.find('input.ipt_check').prop('checked', true);
- // }).on('deselect', function(e, dt, type, indexes) {
- // var $node = table[ type ]( indexes ).nodes().to$();
- // $node.find('input.ipt_check').prop('checked', false);
- // }).on('draw', function(){
- // $('#op').html(options.op_html || '');
- // $('#uc').html(options.uc_html || '');
- // });
+ table.on('select', function(e, dt, type, indexes) {
+ var $node = table[ type ]( indexes ).nodes().to$();
+ $node.find('input.ipt_check').prop('checked', true);
+ }).on('deselect', function(e, dt, type, indexes) {
+ var $node = table[ type ]( indexes ).nodes().to$();
+ $node.find('input.ipt_check').prop('checked', false);
+ }).on('draw', function(){
+ $('#op').html(options.op_html || '');
+ $('#uc').html(options.uc_html || '');
+ });
$('.ipt_check_all').on('click', function() {
if (!jumpserver.checked) {
$(this).closest('table').find('.ipt_check').prop('checked', true);
@@ -354,5 +352,6 @@ jumpserver.initDataTable = function (options) {
table.rows().deselect();
}
});
+
return table;
};
diff --git a/apps/users/api.py b/apps/users/api.py
index aedf0635b..bc881d9b4 100644
--- a/apps/users/api.py
+++ b/apps/users/api.py
@@ -30,9 +30,9 @@ class UserViewSet(BulkModelViewSet):
permission_classes = (IsSuperUser,)
-class UserAndGroupEditApi(generics.RetrieveUpdateAPIView):
+class UserUpdateGroupApi(generics.RetrieveUpdateAPIView):
queryset = User.objects.all()
- serializer_class = serializers.UserAndGroupSerializer
+ serializer_class = serializers.UserUpdateGroupSerializer
permission_classes = (IsSuperUser,)
@@ -72,7 +72,17 @@ class UserUpdatePKApi(generics.UpdateAPIView):
user.public_key = serializer.validated_data['_public_key']
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):
# queryset = UserGroup.objects.all()
# serializer_class = serializers.GroupDetailSerializer
diff --git a/apps/users/serializers.py b/apps/users/serializers.py
index 9d148aa20..48fc820c6 100644
--- a/apps/users/serializers.py
+++ b/apps/users/serializers.py
@@ -16,8 +16,7 @@ from .models import User, UserGroup
class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
- group_display = serializers.SerializerMethodField()
- active_display = serializers.SerializerMethodField()
+ groups_display = serializers.SerializerMethodField()
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
class Meta:
@@ -27,17 +26,16 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
def get_field_names(self, 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
@staticmethod
- def get_group_display(obj):
+ def get_groups_display(obj):
return " ".join([group.name for group in obj.groups.all()])
- @staticmethod
- def get_active_display(obj):
- # TODO: user active state
- return not (obj.is_expired and obj.is_active)
+ # @staticmethod
+ # def get_active_display(obj):
+ # return not (obj.is_expired and obj.is_active)
class UserPKUpdateSerializer(serializers.ModelSerializer):
@@ -54,7 +52,7 @@ class UserPKUpdateSerializer(serializers.ModelSerializer):
return value
-class UserAndGroupSerializer(serializers.ModelSerializer):
+class UserUpdateGroupSerializer(serializers.ModelSerializer):
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
class Meta:
@@ -62,6 +60,26 @@ class UserAndGroupSerializer(serializers.ModelSerializer):
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 Meta:
# model = UserGroup
diff --git a/apps/users/templates/users/user_detail.html b/apps/users/templates/users/user_detail.html
index 49e9fb62e..9b7a48761 100644
--- a/apps/users/templates/users/user_detail.html
+++ b/apps/users/templates/users/user_detail.html
@@ -224,9 +224,8 @@
jumpserver.selected_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 = {
- id: {{ user.id }},
groups: Object.assign([], user_groups)
};
var success = function(data) {
@@ -245,13 +244,11 @@ function updateUserGroups(user_groups) {
});
// clear jumpserver.selected_groups
jumpserver.selected_groups = {};
- toastr.success('{% trans "UserGroup Update Success!" %}')
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
- success: success,
- method: 'PUT'
+ success: success
});
}
$(document).ready(function() {
diff --git a/apps/users/templates/users/user_group_detail.html b/apps/users/templates/users/user_group_detail.html
index 3e00d0055..349233efc 100644
--- a/apps/users/templates/users/user_group_detail.html
+++ b/apps/users/templates/users/user_group_detail.html
@@ -11,52 +11,52 @@
{% endblock %}
{% block content %}
@@ -67,7 +67,7 @@ dd {
@@ -75,7 +75,7 @@ dd {
-
{{ object.name }}
+
{{ user_group.name }}
-
- - {% trans 'Name' %}:
- - {{ object.name }}
-
-
- - {% trans 'Comment' %}:
- - {{ object.comment }}
-
-
- - {% trans 'Created at' %}:
- - {{ object.date_created }}
-
-
- - {% trans 'Users' %}:
- -
- {% for user in object.users.all %}
-
- {% endfor %}
-
-
+
+
+
+ {% trans 'Name' %}: |
+ {{ user_group.name }} |
+
+
+ {% trans 'Create by' %}: |
+ {{ user_group.created_by }} |
+
+
+ {% trans 'Date created' %}: |
+ {{ user_group.date_created }} |
+
+
+ {% trans 'Comment' %}: |
+ {{ user_group.comment }} |
+
+
+
-
+
- {% trans 'Quick modify' %}
+ {% trans 'User' %}
-
+
+
+
+ {% for user in user_group.users.all %}
+
+ {{ user.name }} |
+
+
+ |
+
+ {% endfor %}
@@ -147,35 +156,63 @@ dd {
{% endblock %}
{% block custom_foot_js %}
diff --git a/apps/users/templates/users/user_group_list.html b/apps/users/templates/users/user_group_list.html
index 43101fd87..2ff66b848 100644
--- a/apps/users/templates/users/user_group_list.html
+++ b/apps/users/templates/users/user_group_list.html
@@ -11,7 +11,6 @@
{% trans 'Name' %} |
{% trans 'User Amount' %} |
- {% trans 'Asset Amount' %} |
{% trans 'Comment' %} |
{% trans 'Action' %} |
@@ -43,11 +42,11 @@ $(document).ready(function() {
var detail_btn = '' + cellData + '';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
- {targets: 4, createdCell: function (td, cellData) {
- var innerHtml = cellData.length > 18 ? cellData.substring(0, 18) + '...': cellData;
- $(td).html('' + innerHtml + '');
+ {targets: 3, createdCell: function (td, cellData) {
+ var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
+ $(td).html('' + innerHtml + '');
}},
- {targets: 5, createdCell: function (td, cellData, rowData) {
+ {targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '{% trans "Update" %}'.replace('99991937', cellData);
var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData);
if (rowData.id === 1) {
@@ -56,9 +55,9 @@ $(document).ready(function() {
$(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"},
- {data: function(){return 999}}, {data: "comment"}, {data: "id" }],
+ {data: "comment"}, {data: "id" }],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
@@ -66,7 +65,7 @@ $(document).ready(function() {
var $this = $(this);
function doDelete() {
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 success = function() {
var msg = "{% trans 'Group Deleted.' %}";
@@ -76,7 +75,7 @@ $(document).ready(function() {
var fail = function() {
var msg = "{% trans 'Group Deleting failed.' %}";
swal("{% trans 'Group Delete' %}", msg, "error");
- }
+ };
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
@@ -105,8 +104,8 @@ $(document).ready(function() {
});
if (plain_id_list === []) {
return false;
- };
- var the_url = "{% url 'users:user-group-bulk-update-api' %}";
+ }
+ var the_url = "{% url 'users:api-user-group-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
diff --git a/apps/users/templates/users/user_list.html b/apps/users/templates/users/user_list.html
index d38e1183b..c260bd25b 100644
--- a/apps/users/templates/users/user_list.html
+++ b/apps/users/templates/users/user_list.html
@@ -15,7 +15,6 @@
{% trans 'Username' %} |
{% trans 'Role' %} |
{% trans 'User group' %} |
- {% trans 'Asset num' %} |
{% trans 'Active' %} |
{% trans 'Action' %} |
@@ -56,14 +55,14 @@ $(document).ready(function(){
var innerHtml = cellData.length > 20 ? cellData.substring(0, 20) + '...': cellData;
$(td).html('' + innerHtml + '');
}},
- {targets: 6, createdCell: function (td, cellData) {
+ {targets: 5, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('')
} else {
$(td).html('')
}
}},
- {targets: 7, createdCell: function (td, cellData, rowData) {
+ {targets: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '{% trans "Update" %}'.replace('99991937', cellData);
var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData);
if (rowData.id === 1 || rowData.username == "admin") {
@@ -73,8 +72,8 @@ $(document).ready(function(){
}
}}],
ajax_url: '{% url "users:api-user-list" %}',
- columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" }, {data: "group_display" },
- {data: function(){return 999}}, {data: "active_display" }, {data: "id" }],
+ columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" },
+ {data: "groups_display" }, {data: "is_valid" }, {data: "id" }],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
@@ -224,6 +223,8 @@ $(document).ready(function(){
$form.ajaxSubmit({success: success});
}).on('change', '#id_excel', function() {
$(this).siblings('.help-block').remove();
+}).on('click', '.ipt_check', function () {
+ console.log('Hello')
})
{% endblock %}
diff --git a/apps/users/urls.py b/apps/users/urls.py
index 07561e3ff..a4af64bd1 100644
--- a/apps/users/urls.py
+++ b/apps/users/urls.py
@@ -39,6 +39,7 @@ urlpatterns = [
router = BulkRouter()
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')
@@ -53,7 +54,9 @@ urlpatterns += [
# url(r'^v1/user-groups/(?P\d+)/user/(?P\d+)/$',
# api.DeleteUserFromGroupApi.as_view(), name='delete-user-from-group-api'),
url(r'^v1/users/(?P\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\d+)/users/$',
+ api.UserGroupUpdateUserApi.as_view(), name='api-user-group-update-user'),
]
urlpatterns += router.urls
diff --git a/apps/users/views.py b/apps/users/views.py
index 12a71df21..90468e5bb 100644
--- a/apps/users/views.py
+++ b/apps/users/views.py
@@ -216,10 +216,16 @@ class UserGroupUpdateView(AdminUserRequiredMixin, UpdateView):
class UserGroupDetailView(AdminUserRequiredMixin, DetailView):
model = UserGroup
+ context_object_name = 'user_group'
template_name = 'users/user_group_detail.html'
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)
return super(UserGroupDetailView, self).get_context_data(**kwargs)