Commit dbdb8a58 authored by 右书僮's avatar 右书僮

资产相关API及Web

parent 4c062570
...@@ -3,67 +3,107 @@ ...@@ -3,67 +3,107 @@
from rest_framework import viewsets, generics, mixins from rest_framework import viewsets, generics, mixins
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework_bulk import BulkModelViewSet, BulkDestroyAPIView
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from common.utils import get_object_or_none, signer from common.utils import get_object_or_none, signer
from .hands import IsSuperUserOrTerminalUser, IsSuperUser from .hands import IsSuperUserOrTerminalUser, IsSuperUser
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser, Tag
from . import serializers from . import serializers
class AssetViewSet(IDInFilterMixin, viewsets.ModelViewSet): class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
"""API endpoint that allows Asset to be viewed or edited.""" """API endpoint that allows Asset to be viewed or edited."""
queryset = Asset.objects.all() queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer serializer_class = serializers.AssetSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields = ('id', 'ip', 'hostname') filter_fields = ('id', 'ip', 'hostname')
permission_classes = (IsSuperUser,)
def get_queryset(self): def get_queryset(self):
queryset = super(AssetViewSet, self).get_queryset() queryset = super(AssetViewSet, self).get_queryset()
idc_id = self.request.query_params.get('idc_id', '') idc_id = self.request.query_params.get('idc_id', '')
tags_id = self.request.query_params.get('tag_id', '')
system_users_id = self.request.query_params.get('system_user_id', '')
asset_group_id = self.request.query_params.get('asset_group_id', '') asset_group_id = self.request.query_params.get('asset_group_id', '')
admin_user_id = self.request.query_params.get('admin_user_id', '')
if idc_id: if idc_id:
queryset = queryset.filter(idc__id=idc_id) queryset = queryset.filter(idc__id=idc_id)
if tags_id:
queryset = queryset.filter(tags__id=tags_id)
if system_users_id:
queryset = queryset.filter(system_users__id=system_users_id)
if admin_user_id:
queryset = queryset.filter(admin_user__id=admin_user_id)
if asset_group_id: if asset_group_id:
queryset = queryset.filter(groups__id=asset_group_id) queryset = queryset.filter(groups__id=asset_group_id)
return queryset return queryset
class AssetGroupViewSet(viewsets.ModelViewSet): class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet):
""" API endpoint that allows AssetGroup to be viewed or edited.
some other comment
"""
queryset = AssetGroup.objects.all() queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupSerializer serializer_class = serializers.AssetGroupSerializer
permission_classes = (IsSuperUser,)
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView): class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
queryset = Asset.objects.all() queryset = Asset.objects.all()
serializer_class = serializers.AssetUpdateGroupSerializer serializer_class = serializers.AssetUpdateGroupSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class IDCViewSet(viewsets.ModelViewSet): ## update the asset group, and add or delete the asset to the group
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupUpdateSerializer
permission_classes = (IsSuperUser,)
## update the asset group, and add or delete the system_user to the group
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupUpdateSystemUserSerializer
permission_classes = (IsSuperUser,)
## update the IDC, and add or delete the assets to the IDC
class IDCupdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = IDC.objects.all()
serializer_class = serializers.IDCUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
class IDCViewSet(IDInFilterMixin, BulkModelViewSet):
"""API endpoint that allows IDC to be viewed or edited.""" """API endpoint that allows IDC to be viewed or edited."""
queryset = IDC.objects.all() queryset = IDC.objects.all()
serializer_class = serializers.IDCSerializer serializer_class = serializers.IDCSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class AdminUserViewSet(viewsets.ModelViewSet): class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = AdminUser.objects.all() queryset = AdminUser.objects.all()
serializer_class = serializers.AdminUserSerializer serializer_class = serializers.AdminUserSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class SystemUserViewSet(viewsets.ModelViewSet):
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = SystemUser.objects.all() queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserSerializer serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView): class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
queryset = Asset.objects.all() queryset = Asset.objects.all()
serializer_class = serializers.AssetUpdateSystemUserSerializer serializer_class = serializers.AssetUpdateSystemUserSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
permission_classes = (IsSuperUser,)
# class IDCAssetsApi(generics.ListAPIView): # class IDCAssetsApi(generics.ListAPIView):
# model = IDC # model = IDC
...@@ -115,3 +155,14 @@ class SystemUserAuthApi(APIView): ...@@ -115,3 +155,14 @@ class SystemUserAuthApi(APIView):
return Response({'msg': 'error system user id or username'}, status=401) return Response({'msg': 'error system user id or username'}, status=401)
class TagViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = Tag.objects.all()
serializer_class = serializers.TagSerializer
permission_classes = (IsSuperUser,)
## update the IDC, and add or delete the assets to the IDC
class TagUpdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = Tag.objects.all()
serializer_class = serializers.TagUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
...@@ -37,6 +37,14 @@ class AssetCreateForm(forms.ModelForm): ...@@ -37,6 +37,14 @@ class AssetCreateForm(forms.ModelForm):
self.instance.tags.clear() self.instance.tags.clear()
self.instance.tags.add(*tuple(tags)) self.instance.tags.add(*tuple(tags))
def clean(self):
clean_data = super(AssetCreateForm, self).clean()
ip = clean_data.get('ip')
port = clean_data.get('port')
query = Asset.objects.filter(ip=ip, port=port)
if query:
raise forms.ValidationError('this asset has exists.')
class Meta: class Meta:
model = Asset model = Asset
tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all()) tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all())
...@@ -293,10 +301,10 @@ class AssetTagForm(forms.ModelForm): ...@@ -293,10 +301,10 @@ class AssetTagForm(forms.ModelForm):
super(AssetTagForm, self).__init__(*args, **kwargs) super(AssetTagForm, self).__init__(*args, **kwargs)
def _save_m2m(self): def _save_m2m(self):
super(AssetTagForm, self)._save_m2m()
assets = self.cleaned_data['assets'] assets = self.cleaned_data['assets']
self.instance.asset_set.clear() self.instance.assets.clear()
self.instance.asset_set.add(*tuple(assets)) self.instance.assets.add(*tuple(assets))
super(AssetTagForm, self)._save_m2m()
class Meta: class Meta:
model = Tag model = Tag
......
...@@ -269,6 +269,19 @@ class AssetGroup(models.Model): ...@@ -269,6 +269,19 @@ class AssetGroup(models.Model):
def get_default_idc(): def get_default_idc():
return IDC.initial() return IDC.initial()
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
created_time = models.DateTimeField(auto_now_add=True, verbose_name=_('Create time'))
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
def __unicode__(self):
return self.name
__str__ = __unicode__
class Meta:
db_table = 'tag'
class Asset(models.Model): class Asset(models.Model):
STATUS_CHOICES = ( STATUS_CHOICES = (
...@@ -320,7 +333,7 @@ class Asset(models.Model): ...@@ -320,7 +333,7 @@ class Asset(models.Model):
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added')) date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added'))
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
tags = models.ManyToManyField('Tag', blank=True, verbose_name=_('Tags')) tags = models.ManyToManyField(Tag, related_name='assets', blank=True, verbose_name=_('Tags'))
def __unicode__(self): def __unicode__(self):
return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port} return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port}
...@@ -339,7 +352,7 @@ class Asset(models.Model): ...@@ -339,7 +352,7 @@ class Asset(models.Model):
class Meta: class Meta:
db_table = 'asset' db_table = 'asset'
unique_together = ('ip', 'port') # unique_together = ('ip', 'port')
@classmethod @classmethod
def generate_fake(cls, count=100): def generate_fake(cls, count=100):
...@@ -365,18 +378,7 @@ class Asset(models.Model): ...@@ -365,18 +378,7 @@ class Asset(models.Model):
continue continue
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
created_time = models.DateTimeField(auto_now_add=True, verbose_name=_('Create time'))
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
def __unicode__(self):
return self.name
__str__ = __unicode__
class Meta:
db_table = 'tag'
def init_all_models(): def init_all_models():
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import viewsets, serializers,generics from rest_framework import viewsets, serializers,generics
from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser, Tag
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
class AssetGroupSerializer(serializers.ModelSerializer): class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField() assets_amount = serializers.SerializerMethodField()
# assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True) assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = AssetGroup model = AssetGroup
list_serializer_class = BulkListSerializer
@staticmethod @staticmethod
def get_assets_amount(obj): def get_assets_amount(obj):
...@@ -31,7 +32,43 @@ class AssetUpdateSystemUserSerializer(serializers.ModelSerializer): ...@@ -31,7 +32,43 @@ class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
model = Asset model = Asset
fields = ['id', 'system_users'] fields = ['id', 'system_users']
## update the asset group, and add or delete the asset to the group
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'assets']
## update the asset group, and add or delete the system_user to the group
class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'system_users']
## update the IDC, and add or delete the assets to the IDC
class IDCUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = IDC
fields = ['id', 'assets']
## tags API
class TagSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Tag
list_serializer_class = BulkListSerializer
@staticmethod
def get_assets_amount(obj):
return obj.assets.count()
class AdminUserSerializer(serializers.ModelSerializer): class AdminUserSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = AdminUser model = AdminUser
...@@ -52,6 +89,20 @@ class SystemUserSerializer(serializers.ModelSerializer): ...@@ -52,6 +89,20 @@ class SystemUserSerializer(serializers.ModelSerializer):
return fields return fields
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'assets']
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'asset_groups']
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer): class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# system_users = SystemUserSerializer(many=True, read_only=True) # system_users = SystemUserSerializer(many=True, read_only=True)
# admin_user = AdminUserSerializer(many=False, read_only=True) # admin_user = AdminUserSerializer(many=False, read_only=True)
...@@ -96,8 +147,9 @@ class AssetGrantedSerializer(serializers.ModelSerializer): ...@@ -96,8 +147,9 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
return ', '.join([system_user.username for system_user in obj.system_users.all()]) return ', '.join([system_user.username for system_user in obj.system_users.all()])
class IDCSerializer(serializers.ModelSerializer): class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField() assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = IDC model = IDC
...@@ -110,3 +162,11 @@ class IDCSerializer(serializers.ModelSerializer): ...@@ -110,3 +162,11 @@ class IDCSerializer(serializers.ModelSerializer):
fields = super(IDCSerializer, self).get_field_names(declared_fields, info) fields = super(IDCSerializer, self).get_field_names(declared_fields, info)
fields.append('assets_amount') fields.append('assets_amount')
return fields return fields
class TagUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Tag
fields = ['id', 'assets']
\ No newline at end of file
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
{% block modal_body %} {% block modal_body %}
{% load bootstrap %} {% load bootstrap %}
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p> <p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
<div class="ydxbd" id="ydxbd" style="display: block;">
<div class="ydxbd" id="ydxbd" style="display: block;">
<div> <div>
<p id="tags_p"> <p id="tags_p">
<a href="/assets/asset-by-tag/5"> <a href="/assets/asset-by-tag/5">
...@@ -15,21 +14,25 @@ ...@@ -15,21 +14,25 @@
</a> </a>
</p> </p>
</div> </div>
</div> </div>
<form method="post" class="form-horizontal" action="" id="fm_asset_bulk_update"> <form method="post" class="form-horizontal" action="" id="fm_asset_bulk_update">
<div class="form-group"> <div class="form-group">
<label class="control-label col-sm-2 col-lg-2 " for="id_role">{% trans "Role" %}</label> <label class="control-label col-sm-2 col-lg-2 " for="id_type">{% trans "System Type" %}</label>
<div class=" col-sm-9 col-lg-9 "> <div class=" col-sm-9 col-lg-9 ">
<select class=" select2 form-control" id="id_role" name="role"> <select class=" select2 form-control" id="id_type" name="type">
<option value="">---------</option> <option value="">---------</option>
<option value="Admin">{% trans "Admin" %}</option> <option value="Server">{% trans "Server" %}</option>
<option value="User">{% trans "User" %}</option> <option value="VM">{% trans "VM" %}</option>
<option value="Switch">{% trans "Switch" %}</option>
<option value="Storage">{% trans "Storage" %}</option>
<option value="Router">{% trans "Router" %}</option>
<option value="Firewall">{% trans "Firewall" %}</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label for="groups" class="col-sm-2 control-label">{% trans 'Groups' %}</label> <div class="form-group">
<label for="groups" class="col-sm-2 control-label">{% trans 'Asset Groups' %}</label>
<div class="col-sm-9" id="select2-container"> <div class="col-sm-9" id="select2-container">
<select name="groups" id="select2_groups" data-placeholder="{% trans 'Select Group' %}" class="select2 form-control m-b" multiple> <select name="groups" id="select2_groups" data-placeholder="{% trans 'Select Group' %}" class="select2 form-control m-b" multiple>
{% for group in groups %} {% for group in groups %}
...@@ -38,6 +41,18 @@ ...@@ -38,6 +41,18 @@
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label for="users" class="col-sm-2 control-label">{% trans 'System Users' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="system_users" id="select2_users" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
{% for system_user in system_users %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-9 col-lg-9 col-sm-offset-2"> <div class="col-sm-9 col-lg-9 col-sm-offset-2">
<div class="checkbox checkbox-success"> <div class="checkbox checkbox-success">
...@@ -48,27 +63,16 @@ ...@@ -48,27 +63,16 @@
<div class="form-group"> <div class="form-group">
<label class="control-label col-sm-2 col-lg-2 " for="id_tags">标签集合</label> <label class="control-label col-sm-2 col-lg-2 " for="id_tags">标签集合</label>
<div class=" col-sm-9 col-lg-9 "> <div class=" col-sm-9 col-lg-9 ">
<select multiple="multiple" class="select2 form-control" data-placeholder="Select asset tags" id="tags" name="tags"> <select multiple="multiple" class="select2 form-control" data-placeholder="Select asset tags" id="tags" name="tags">
<option value="1">物理机</option> {% for tag in tags %}
<option value="2">虚拟机</option> <option value="{{ tag.id }}">{{ tag.name }}</option>
<option value="3">数据库备份</option> {% endfor %}
<option value="4">亦庄机房</option> </select>
<option value="5">三年质保</option>
</select>
<p class="help-block"> <p class="help-block">
最多5个标签,单个标签最长8个汉字,按回车确认 最多5个标签,单个标签最长8个汉字,按回车确认
</p> </p>
</div> </div>
</div> </div>
......
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}asset_group_bulk_update_modal{% endblock %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_title%}{% trans "Update Asset Group" %}{% endblock %}
{% block modal_body %}
{% load bootstrap %}
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
<form method="post" class="form-horizontal" action="" id="fm_asset_group_bulk_update">
<div class="form-group">
<label for="assets" class="col-sm-2 control-label">{% trans 'Assets' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="assets" id="select2_groups" data-placeholder="{% trans 'Select Asset' %}" class="select2 form-control m-b" multiple>
{% for asset in assets %}
<option value="{{ asset.id }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="system_users" class="col-sm-2 control-label">{% trans 'System Users' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="system_users" id="select2_groups" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
{% for system_user in system_users %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-lg-9 col-sm-offset-2">
<div class="checkbox checkbox-success">
<input type="checkbox" name="enable_otp" checked id="id_enable_otp"><label for="id_enable_otp">{% trans 'Enable-OTP' %}</label>
</div>
</div>
</div>
</form>
{% endblock %}
{% block modal_confirm_id %}btn_asset_group_bulk_update{% endblock %}
\ No newline at end of file
...@@ -88,29 +88,30 @@ ...@@ -88,29 +88,30 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-hover"> <table class="table table-hover" id="system_user_assets_table">
<thead> <thead>
<tr> <tr>
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Alive' %}</th> <th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in page_obj %} {# {% for asset in page_obj %}#}
<tr> {# <tr>#}
<td>{{ asset.hostname }}</td> {# <td>{{ asset.hostname }}</td>#}
<td>{{ asset.ip }}</td> {# <td>{{ asset.ip }}</td>#}
<td>{{ asset.port }}</td> {# <td>{{ asset.port }}</td>#}
<td>Alive</td> {# <td>Alive</td>#}
</tr> {# </tr>#}
{% endfor %} {# {% endfor %}#}
</tbody> </tbody>
</table> </table>
<div class="row"> {# <div class="row">#}
{% include '_pagination.html' %} {# {% include '_pagination.html' %}#}
</div> {# </div>#}
</div> </div>
</div> </div>
</div> </div>
...@@ -164,15 +165,15 @@ ...@@ -164,15 +165,15 @@
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for asset in assets_remain %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-info btn-sm">{% trans 'Replace' %}</button> <button type="button" class="btn btn-info btn-sm btn-replace-asset-admin_user">{% trans 'Replace' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
...@@ -192,15 +193,15 @@ ...@@ -192,15 +193,15 @@
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for asset_group in asset_groups %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-warning btn-sm">{% trans 'Replace' %}</button> <button type="button" class="btn btn-warning btn-sm btn-replace-asset_groups-admin_user">{% trans 'Replace' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
...@@ -218,26 +219,181 @@ ...@@ -218,26 +219,181 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} Array.prototype.remove = function(val) {
{# var status = $(obj).prop('checked');#} var index = this.indexOf(val);
{##} if (index > -1) {
{# $.ajax({#} this.splice(index, 1);
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} }
{# type: "PUT",#} };
{# data: {#} Array.prototype.unique = function(){
{# 'is_active': status#} var res = [];
{# },#} var json = {};
{# success: function (data, status) {#} for(var i = 0; i < this.length; i++){
{# console.log(data)#} if(!json[this[i]]){
{# },#} res.push(this[i]);
{# error: function () {#} json[this[i]] = 1;
{# console.log('error')#} }
{# }#} }
{# })#} return res;
{# }#} };
$(document).ready(function () { function objectRemove(obj, name, url, data) {
$('.select2').select2(); function doRemove() {
var body = data;
var success = function() {
swal('Remove!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Remove"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure remove ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doRemove()
});
}
jumpserver.assets_selected = {};
jumpserver.asset_groups_selected = {};
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.asset_groups_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.asset_groups_selected[data.id]
});
var options = {
ele: $('#system_user_assets_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_remove" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-replace-asset-admin_user', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
jumpserver.asset_groups_selected = {};
var $data_table = $("#system_user_assets_table").DataTable();
var assets = [];
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var data = [];
var admin_user_id = {{ admin_user.id }};
var the_url = '{% url "api-assets:asset-list" %}';
for (var i=0; i<assets.length; i++) {
data.push({"id": assets[i], "admin_user": admin_user_id});
}
APIUpdateAttr({
url: the_url,
body: JSON.stringify(data),
method: 'PATCH'
});
$data_table.ajax.reload();
})
.on('click', '.btn-replace-asset_groups-admin_user', function () {
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
return false;
}
jumpserver.assets_selected = {};
var $data_table = $("#system_user_assets_table").DataTable();
var asset_groups = [];
var assets = [];
var data = [];
var the_url = '{% url "api-assets:asset-list" %}';
$.map(jumpserver.asset_groups_selected, function(value, index) {
asset_groups.push(parseInt(index));
});
$.ajax({
url: '{% url "api-assets:asset-group-list" %}?id__in=['+asset_groups.join(',')+']',
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i=0; i<result.length; i++) {
for (var j=0; j<result[i]['assets'].length; j++) {
assets.push(result[i]['assets'][j])
}
}
for (var z=0; z<assets.length; z++) {
data.push({"id":assets[z], "admin_user":{{admin_user.id}} });
}
APIUpdateAttr({
url: the_url,
body: JSON.stringify(data),
method: 'PATCH'
}); });
</script> $data_table.ajax.reload();
}
});
})
.on('click', '.btn_asset_remove', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:admin-user-detail' pk=admin_user.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
var delete_asset_id = $(this).data('aid');
$.ajax({
url: the_url,
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i=0; i<result['assets'].length; i++) {
assets.push(result['assets'][i])
}
assets.remove(delete_asset_id);
var data = {"assets": assets};
objectRemove($this, name, the_url, data);
}
});
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -23,6 +23,18 @@ ...@@ -23,6 +23,18 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
...@@ -48,8 +60,72 @@ $(document).ready(function(){ ...@@ -48,8 +60,72 @@ $(document).ready(function(){
ajax_url: '{% url "api-assets:admin-user-list" %}', ajax_url: '{% url "api-assets:admin-user-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} }, columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} },
{data: "comment" }, {data: "id" }], {data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $("#admin_user_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:admin-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#admin_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (plain_id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:admin-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected Admin Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Admin Users Deleted.' %}";
swal("{% trans 'Admin Users Delete' %}", msg, "success");
$('#admin_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Admin Users Deleting failed.' %}";
swal("{% trans 'Admin Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}); });
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -200,7 +200,7 @@ ...@@ -200,7 +200,7 @@
<i class="fa fa-info-circle"></i> {% trans 'Asset groups' %} <i class="fa fa-info-circle"></i> {% trans 'Asset groups' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table group_edit"> <table class="table group_edit" id="add-asset2group">
<tbody> <tbody>
<form> <form>
<tr> <tr>
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
<i class="fa fa-info-circle"></i> {% trans 'System users' %} <i class="fa fa-info-circle"></i> {% trans 'System users' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table group_edit"> <table class="table group_edit" id="add-asset2systemuser">
<tbody> <tbody>
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
...@@ -288,7 +288,7 @@ function updateAssetGroups(groups) { ...@@ -288,7 +288,7 @@ function updateAssetGroups(groups) {
$.map(jumpserver.groups_selected, function(group_name, index) { $.map(jumpserver.groups_selected, function(group_name, index) {
$('#opt_' + index).remove(); $('#opt_' + index).remove();
// change tr html of user groups. // change tr html of user groups.
$('.group_edit tbody').append( $('#add-asset2group tbody').append(
'<tr>' + '<tr>' +
'<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' + '<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' + '<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
...@@ -316,7 +316,7 @@ function updateAssetSystem(system_users) { ...@@ -316,7 +316,7 @@ function updateAssetSystem(system_users) {
$.map(jumpserver.groups_selected, function(name, index) { $.map(jumpserver.groups_selected, function(name, index) {
$('#opt_' + index).remove(); $('#opt_' + index).remove();
$('.group_edit tbody').append( $('#add-asset2systemuser tbody').append(
'<tr>' + '<tr>' +
'<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' + '<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' + '<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' +
...@@ -418,7 +418,6 @@ $(document).ready(function () { ...@@ -418,7 +418,6 @@ $(document).ready(function () {
var system_users = $('.bdg_group').map(function () { var system_users = $('.bdg_group').map(function () {
return $(this).data('sid'); return $(this).data('sid');
}).get(); }).get();
console.log(system_users);
updateAssetSystem(system_users) updateAssetSystem(system_users)
}) })
......
...@@ -48,10 +48,28 @@ ...@@ -48,10 +48,28 @@
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Alive' %}</th> <th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{# {% for asset in assets %}#}
{# <tr id="bdg_asset" data-aid="{{ asset.id }}">#}
{# <td>{{ asset.hostname }}</td>#}
{# <td>{{ asset.ip }}</td>#}
{# <td>{{ asset.port }}</td>#}
{# {% if asset.is_active %}#}
{# <td><i class="fa fa-circle text-navy"></i></td>#}
{# {% else %}#}
{# <td><i class="fa fa-circle text-danger"></i></td>#}
{# {% endif %}#}
{# <td>#}
{# <a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="{{ asset.id }}">{% trans "Delete" %}</a>#}
{# <a class="btn btn-xs btn-info m-l-xs btn_asset_update" data-aid="{{ asset.id }}" href="{% url 'assets:asset-update' pk=asset.id %}">{% trans "Update" %}</a>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
</tbody> </tbody>
</table> </table>
</div> </div>
...@@ -70,14 +88,14 @@ ...@@ -70,14 +88,14 @@
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select assets' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select assets' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %} {% for asset in assets_remain %}
<option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option> <option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Add' %}</button> <button type="button" class="btn btn-primary btn-sm btn-asset-add-groups">{% trans 'Add' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
...@@ -91,29 +109,29 @@ ...@@ -91,29 +109,29 @@
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %} <i class="fa fa-info-circle"></i> {% trans 'Associate system user' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table system-user-table">
<tbody> <tbody>
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for system_user in system_users_remain %} {% for system_user in system_users_remain %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option> <option value="{{ system_user.id }}" id="opt_{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-info btn-sm">{% trans 'Associate' %}</button> <button type="button" class="btn btn-info btn-sm btn-asset-add-groups-system-users">{% trans 'Associate' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for system_user in system_users %} {% for system_user in system_users %}
<tr> <tr>
<td ><b>{{ group.name }}</b></td> <td ><b class="bdg_system_user" data-sid={{ system_user.id }}>{{ system_user.name }}</b></td>
<td> <td>
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button> <button class="btn btn-danger btn-xs pull-right btn_leave_asset_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
...@@ -132,53 +150,249 @@ ...@@ -132,53 +150,249 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
$(document).ready(function () { jumpserver.assets_selected = {};
$('.select2').select2(); jumpserver.system_users_selected = {};
function updateAssetsGroup(assets) {
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var body = {
assets: Object.assign([], assets)
};
var success = function(data) {
$('select2-selection__rendered').empty();
$('#groups_selected').val('');
$('#asset_list_table > tbody').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
var url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace(99991937, index);
asset = $.ajax({
url: url,
method: "GET",
dataType: "json",
success: function (data, textStatus) {
var add_tr = '<tr id="bdg_asset" data-aid="'+data.id+'">'+
'<td>'+data.hostname+'</td>'+
'<td>'+data.ip+'</td>'+
'<td>'+data.port+'</td>'+
'<td>status</td>'+
'<td>'+
'<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="'+data.id+'">{% trans "Delete" %}</a>'+
'<a class="btn btn-xs btn-info m-l-xs btn_asset_update" data-aid="'+data.id+'" href="'+'{% url "assets:asset-update" pk=99991937 %}'.replace(99991937, data.id)+'">{% trans "Update" %}</a>'+
'</td>'+
'</tr>';
(data.is_active == true) ? tr = add_tr.replace('<td>status</td>', '<td><i class="fa fa-circle text-navy"></i></td>'): tr = add_tr.replace('<td>status</td>', '<td><i class="fa fa-circle text-danger"></i></td>');
$('#asset_list_table > tbody').append(tr);
}
});
});
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
function objectDelete(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
function updateAssetGroupSystemUsers(system_users) {
var the_url = "{% url 'api-assets:asset-groups-update-systemusers' pk=asset_group.id %}";
var body = {
system_users: Object.assign([], system_users)
};
var success = function(data) {
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.system_users_selected, function(system_user, index) {
$('#opt_' + index).remove();
$('.system-user-table tbody').append(
'<tr>' +
'<td><b class="bdg_group" data-sid="' + index + '">' + system_user + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
jumpserver.system_users_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
Array.prototype.unique = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
};
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.system_users_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.system_users_selected[data.id]
});
var options = { var options = {
ele: $('#asset_list_table'), ele: $('#asset_list_table'),
buttons: [], buttons: [],
order: [], order: [],
select: [],
columnDefs: [ columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) { {targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "perms:asset-permission-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{targets: 2, createdCell: function (td, cellData, rowData) { {targets: 4, createdCell: function (td, cellData) {
var dataLength = cellData.length;
$(td).html(dataLength);
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
var dataLength = cellData.length;
$(td).html(dataLength);
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var dataLength = cellData.length;
$(td).html(dataLength);
}},
{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: 6, createdCell: function (td, cellData, rowData) { {targets: 5, createdCell: function (td, cellData, rowData) {
var btn = '<button class="btn btn-danger btn-xs btn_del_permission disabled" id=99991937 type="button" style="float: right;"><i class="fa fa-minus"></i></button>'; var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
if (rowData.is_inherited) { var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
$(td).html(btn) $(td).html(update_btn + del_btn)
} else {
btn = btn.replace('99991937', cellData);
$(td).html(btn.replace('disabled', ''));
}
}} }}
], ],
ajax_url: '{% url "api-perms:asset-permission-list" %}?user={{ user.id }}', ajax_url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets" }, {data: "asset_groups"}, columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "system_users"}, {data: "is_active"}, {data: "id"}] {data: "type" }, {data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
}) })
</script>
.on('click', '.btn-asset-add-groups', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
jumpserver.system_users_selected = {};
var $data_table = $("#asset_list_table").DataTable();
var assets = [];
$.ajax({
url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
method: 'GET',
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var body = {"assets": assets};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
{# TODO: reflash the table and reset the jumpserver variables #}
{# window.location.href='{% url "assets:asset-group-detail" pk=asset_group.id %}';#}
}
});
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
$('#asset_list_table > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
var data = {"assets": assets};
objectDelete($this, name, the_url, data);
})
.on('click', '.btn-asset-add-groups-system-users', function () {
if (Object.keys(jumpserver.system_users_selected).length === 0) {
return false;
}
jumpserver.assets_selected = {};
var system_users = $('.bdg_system_user').map(function() {
return $(this).data('sid');
}).get();
$.map(jumpserver.system_users_selected, function(value, index) {
system_users.push(parseInt(index));
$('#opt_' + index).remove();
});
system_users.unique();
updateAssetGroupSystemUsers(system_users);
})
.on('click', '.btn_leave_asset_group', function () {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_system_user');
var sid = $badge.data('sid');
var name = $badge.html() || $badge.text();
$('system-user-table').append(
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
);
$tr.remove();
var system_users = $('.bdg_system_user').map(function () {
return $(this).data('sid');
}).get();
updateAssetGroupSystemUsers(system_users)
})
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -21,6 +21,20 @@ ...@@ -21,6 +21,20 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% include 'assets/_asset_group_bulk_update_modal.html' %}
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
...@@ -43,17 +57,125 @@ $(document).ready(function(){ ...@@ -43,17 +57,125 @@ $(document).ready(function(){
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}}], }}],
ajax_url: '{% url "api-assets:asset-group-list" %}', ajax_url: '{% url "api-assets:asset-group-list" %}',
columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}] columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
}) })
.on('click', '.btn_asset_group_delete', function () {
.on('click', '.btn_asset_group_delete', function () {
var $this = $(this); var $this = $(this);
var $data_table = $('#asset_groups_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid'); var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid); var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url); objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_groups_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = '{% url "api-assets:asset-group-list" %}';
console.log(plain_id_list);
console.log(the_url);
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected groups !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Group Deleted.' %}";
swal("{% trans 'Group Delete' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Group Deleting failed.' %}";
swal("{% trans 'Group Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
}); });
}
function doUpdate() {
$('#asset_group_bulk_update_modal').modal('show');
}
switch(action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
.on('click', '#btn_asset_group_bulk_update', function () {
var json_data = $("#fm_asset_group_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.assets != undefined) {
body.assets = json_data.assets;
}
if (typeof body.assets === 'string') {
body.assets = [parseInt(body.assets)]
} else if(typeof body.assets === 'array') {
var new_assets = body.assets.map(Number);
body.assets = new_assets;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)];
} else if (typeof body.system_users === 'array') {
var new_system_users = body.system_users.map(Number);
body.system_users = new_system_users;
}
var post_list = [];
var $data_table = $('#asset_groups_list_table').DataTable()
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = '{% url "api-assets:asset-group-list" %}';
var success = function() {
var msg = "{% trans 'The selected asset groups has been updated successfully.' %}";
swal("{% trans 'AssetGroup Updated' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
{# console.log(JSON.stringify(post_list));#}
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_group_bulk_update_modal').modal('hide');
});
</script> </script>
{% endblock %} {% endblock %}
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
<option value="delete">{% trans 'Delete selected' %}</option> <option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option> <option value="update">{% trans 'Update selected' %}</option>
<option value="deactive">{% trans 'Deactive selected' %}</option> <option value="deactive">{% trans 'Deactive selected' %}</option>
<option value="active">{% trans 'Active' %}</option>
</select> </select>
<div class="input-group-btn pull-left" style="padding-left: 5px;"> <div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary"> <button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
...@@ -81,12 +82,13 @@ ...@@ -81,12 +82,13 @@
</div> </div>
</div> </div>
{% include 'assets/_asset_import_modal.html' %} {% include 'assets/_asset_import_modal.html' %}
{% include 'assets/_asset_bulk_update_modal.html' %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script> <script src="{% static 'js/jquery.form.min.js' %}"></script>
<script type="text/javascript"> <script type="text/javascript">
window.onload = function (){ window.onload = function (){
var tag_on = document.getElementsByName("tag_on"); var tag_on = document.getElementsByName("tag_on");
var oDiv = document.getElementById("ydxbd"); var oDiv = document.getElementById("ydxbd");
if(tag_on.length > 0){ if(tag_on.length > 0){
...@@ -94,16 +96,16 @@ ...@@ -94,16 +96,16 @@
} }
}; };
function tagShow() { function tagShow() {
var oDiv = document.getElementById("ydxbd"); var oDiv = document.getElementById("ydxbd");
if (oDiv.style.display == 'none'){ if (oDiv.style.display == 'none'){
oDiv.style.display = "block"; oDiv.style.display = "block";
}else{ }else{
oDiv.style.display = "none"; oDiv.style.display = "none";
} }
} //onload; } //onload;
$(document).ready(function(){ $(document).ready(function(){
var options = { var options = {
ele: $('#asset_list_table'), ele: $('#asset_list_table'),
columnDefs: [ columnDefs: [
...@@ -129,7 +131,6 @@ ...@@ -129,7 +131,6 @@
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData); var update_btn = '<a href="{% url "assets:asset-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_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData); var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}} }}
], ],
ajax_url: '{% url "api-assets:asset-list" %}', ajax_url: '{% url "api-assets:asset-list" %}',
...@@ -139,13 +140,13 @@ ...@@ -139,13 +140,13 @@
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
var table = jumpserver.initDataTable(options); var table = jumpserver.initDataTable(options);
$('.btn_export').click(function () { $('.btn_export').click(function () {
var assets = []; var assets = [];
var rows = table.rows('.selected').data(); var rows = table.rows('.selected').data();
$.each(rows, function (index, obj) { $.each(rows, function (index, obj) {
assets.push(obj.id) assets.push(obj.id)
}); });
console.log(assets);
$.ajax({ $.ajax({
url: "{% url "assets:asset-export" %}", url: "{% url "assets:asset-export" %}",
method: 'POST', method: 'POST',
...@@ -159,7 +160,6 @@ ...@@ -159,7 +160,6 @@
} }
}) })
}); });
$('#btn_asset_import').click(function() { $('#btn_asset_import').click(function() {
var $form = $('#fm_asset_import'); var $form = $('#fm_asset_import');
$form.find('.help-block').remove(); $form.find('.help-block').remove();
...@@ -179,15 +179,150 @@ ...@@ -179,15 +179,150 @@
} }
$form.ajaxSubmit({success: success}); $form.ajaxSubmit({success: success});
}) })
})
}) .on('click', '.btn_asset_delete', function () {
.on('click', '.btn_asset_delete', function () {
var $this = $(this); var $this = $(this);
var $data_table = $("#asset_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid'); var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid); var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url); objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (plain_id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:asset-list' %}";
function doDeactive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = false;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doActive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = true;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
}); });
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch(action) {
case 'deactive':
doDeactive();
break;
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
case 'active':
doActive();
break;
default:
break;
}
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)]
} else if(typeof body.system_users === 'array') {
var new_users = body.system_users.map(Number);
body.system_users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
console.log(JSON.stringify(post_list));
console.log(the_url);
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
$('#asset_bulk_update_modal').modal('hide');
});
</script> </script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -77,80 +77,27 @@ ...@@ -77,80 +77,27 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-hover"> <table class="table table-striped table-bordered table-hover " id="tag_assets_table" >
<thead> <thead>
<tr> <tr>
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Alive' %}</th> <th>{% trans 'Type' %}</th>
<th>{% trans 'Valid' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in page_obj %}
<tr>
<td>{{ asset.hostname }}</td>
<td>{{ asset.ip }}</td>
<td>{{ asset.port }}</td>
<td>Alive</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
<div class="row">
{% include '_pagination.html' %}
</div>
</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-primary">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %} <i class="fa fa-info-circle"></i> {% trans 'Add asset to this tag' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="50%">{% trans 'repush system user' %}:</td>
<td>
<span style="float: right">
<button class="btn btn-danger btn-xs" type="button"><i class="fa fa-refresh"></i></button>
</span>
</td>
</tr>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Associate' %}</button>
</td>
</tr>
</form>
{% for group in user.groups.all %}
<tr>
<td ><b>{{ group.name }}</b></td>
<td>
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add asset to this group' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
...@@ -158,27 +105,19 @@ ...@@ -158,27 +105,19 @@
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset user' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for asset in assets_remain %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-info btn-sm">{% trans 'Add' %}</button> <button type="button" class="btn btn-info btn-sm btn-tag-asset-add">{% trans 'Add' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for group in user.groups.all %}
<tr>
<td ><b>{{ group.name }}</b></td>
<td>
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
...@@ -194,26 +133,147 @@ ...@@ -194,26 +133,147 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} jumpserver.assets_selected = {};
{# var status = $(obj).prop('checked');#}
{##} function updateTagAssets(assets) {
{# $.ajax({#} var the_url = "{% url 'api-assets:tag-update-assets' pk=tag.id %}";
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} var body = {
{# type: "PUT",#} assets: Object.assign([], assets)
{# data: {#} };
{# 'is_active': status#} var $data_table = $("#tag_assets_table").DataTable();
{# },#} var success = function(data) {
{# success: function (data, status) {#} $('.select2-selection__rendered').empty();
{# console.log(data)#} $.map(jumpserver.assets_selected, function(asset_ip, index) {
{# },#} $('#opt_' + index).remove();
{# error: function () {#} $data_table.ajax.reload();
{# console.log('error')#} });
{# }#} jumpserver.groups_selected = {};
{# })#} };
{# }#} APIUpdateAttr({
$(document).ready(function () { url: the_url,
$('.select2').select2(); body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function deleteTagAssets(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
}) })
</script> .on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
});
var options = {
ele: $('#tag_assets_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?tag_id={{ tag.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-tag-asset-add', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var assets=[];
var $data_table = $("#tag_assets_table").DataTable();
$.ajax({
url: '{% url "api-assets:asset-list" %}',
method: 'GET',
data: {"tag_id": {{ tag.id }}},
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
updateTagAssets(assets);
$data_table.ajax().reload();
}
})
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:tag-update-assets' pk=tag.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
$('#tag_assets_table > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
var data = {"assets": assets};
deleteTagAssets($this, name, the_url, data);
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
{% extends '_base_list.html' %} {% extends '_base_list.html' %}
{% load i18n %} {% load i18n static %}
{% load common_tags %} {#{% load common_tags %}#}
{% block content_left_head %} {% block custom_head_css_js %}
<a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a> <link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %} {% endblock %}
{#{% block content_left_head %}#}
{% block table_head %} {# <a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a>#}
<th class="text-center"> {#{% endblock %}#}
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')"> {#{% block table_head %}#}
</th> {# <th class="text-center">#}
<th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th> {# <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">#}
{# </th>#}
{# <th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th>#}
{# <th class="text-center">{% trans 'Asset num' %}</th>#}
{# <th class="text-center"></th>#}
{#{% endblock %}#}
{#{% block table_body %}#}
{# {% for asset_tag in asset_tags_list %}#}
{# <tr class="gradeX">#}
{# <td class="text-center">#}
{# <input type="checkbox" name="checked" value="{{ asset_tag.id }}">#}
{# </td>#}
{# <td class="text-center">#}
{# <a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}">#}
{# {{ asset_tag.name }}#}
{# </a>#}
{# </td>#}
{# <td class="text-center">{{ asset_tag.asset_set.count }}</td>#}
{# <td class="text-center">#}
{# <a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>#}
{# <a onclick="objectDelete(this,'{{ asset_tag.name }}','{% url 'assets:asset-tag-delete' asset_tag.id %}')" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
{#{% endblock %}#}
{#{% block content_bottom_left %}#}
{# <form id="" method="get" action="" class=" mail-search">#}
{# <div class="input-group">#}
{# <select class="form-control m-b" style="width: auto">#}
{# <option>{% trans 'Delete selected' %}</option>#}
{# <option>{% trans 'Update selected' %}</option>#}
{# <option>{% trans 'Deactive selected' %}</option>#}
{# <option>{% trans 'Export selected' %}</option>#}
{# </select>#}
{# <div class="input-group-btn pull-left" style="padding-left: 5px;">#}
{# <button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">#}
{# {% trans 'Submit' %}#}
{# </button>#}
{# </div>#}
{# </div>#}
{# </form>#}
{#{% endblock %}#}
{% block table_search %}{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url "assets:asset-tag-create" %}" class="btn btn-sm btn-primary"> {% trans "Create Tag" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="tag_list_table" >
<thead>
<tr>
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
<th class="text-center">{% trans 'TagName' %}</th>
<th class="text-center">{% trans 'Asset num' %}</th> <th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center"></th> <th class="text-center">{% trans 'Action' %}</th>
{% endblock %}
{% block table_body %}
{% for asset_tag in asset_tags_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="checked" value="{{ asset_tag.id }}">
</td>
<td class="text-center">
<a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}">
{{ asset_tag.name }}
</a>
</td>
<td class="text-center">{{ asset_tag.asset_set.count }}</td>
<td class="text-center">
<a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>
<a onclick="objectDelete(this,'{{ asset_tag.name }}','{% url 'assets:asset-tag-delete' asset_tag.id %}')" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>
</td>
</tr> </tr>
{% endfor %} </thead>
{% endblock %} <tbody>
</tbody>
{% block content_bottom_left %} </table>
<form id="" method="get" action="" class=" mail-search"> <div id="actions" class="hide">
<div class="input-group"> <div class="input-group">
<select class="form-control m-b" style="width: auto"> <select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option>{% trans 'Delete selected' %}</option> <option value="delete">{% trans 'Delete selected' %}</option>
<option>{% trans 'Update selected' %}</option> <option value="update">{% trans 'Update selected' %}</option>
<option>{% trans 'Deactive selected' %}</option>
<option>{% trans 'Export selected' %}</option>
</select> </select>
<div class="input-group-btn pull-left" style="padding-left: 5px;"> <div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary"> <button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %} {% trans 'Submit' %}
</button> </button>
</div> </div>
</div> </div>
</form> </div>
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script type="text/javascript">
$(document).ready(function () {
var options = {
ele: $("#tag_list_table"),
columnDefs:[
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url 'assets:asset-tag-detail' 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_tag_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-tag-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" },{data: "id"}]
};
jumpserver.initDataTable(options);
})
.on('click', '.btn_tag_delete', function () {
var $this = $(this);
var $data_table = $('#tag_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-tag-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
{% block custom_head_css_js %} {% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet"> <link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script> <script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<style type="text/css">
</style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
...@@ -42,6 +45,7 @@ ...@@ -42,6 +45,7 @@
</a> </a>
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="idc_assets_table" > <table class="table table-striped table-bordered table-hover " id="idc_assets_table" >
<thead> <thead>
...@@ -59,13 +63,27 @@ ...@@ -59,13 +63,27 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
</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-primary">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Attach to assets ' %} <i class="fa fa-info-circle"></i> {% trans 'Attach assets to IDC ' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
...@@ -75,14 +93,14 @@ ...@@ -75,14 +93,14 @@
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %} {% for asset in assets_remain %}
<option value="{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option> <option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Attach' %}</button> <button type="button" class="btn btn-primary btn-sm btn-asset-attach">{% trans 'Attach Assets' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
...@@ -96,19 +114,77 @@ ...@@ -96,19 +114,77 @@
</div> </div>
</div> </div>
</div> </div>
{% include 'assets/_asset_bulk_update_modal.html' %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script src="{% static 'js/jquery.form.min.js' %}"></script>
$(document).ready(function () { <script>
$('.select2').select2();
jumpserver.assets_selected = {};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
function updateIDCAssets(assets) {
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
var $data_table = $("#idc_assets_table").DataTable();
var success = function(data) {
$('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
$('#opt_' + index).remove();
$data_table.ajax.reload();
});
jumpserver.groups_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function deleteIDCAssets(assets) {
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
var $data_table = $("#idc_assets_table").DataTable();
var success = function(data) {
$data_table.ajax.reload();
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
});
var options = { var options = {
ele: $('#idc_assets_table'), ele: $('#idc_assets_table'),
buttons: [], buttons: [],
order: [], order: [],
columnDefs: [ columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) { {targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{targets: 5, createdCell: function (td, cellData) { {targets: 5, createdCell: function (td, cellData) {
...@@ -120,9 +196,173 @@ ...@@ -120,9 +196,173 @@
}}], }}],
ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}', ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}',
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" }, columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }] {data: "type" }, {data: "is_active" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn-asset-attach', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var assets=[];
var $data_table = $("#idc_assets_table").DataTable();
$.ajax({
url: '{% url "api-assets:asset-list" %}',
method: 'GET',
data: {"idc_id": {{ idc.id }}},
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
updateIDCAssets(assets);
}
});
})
.on('click', '#btn_bulk_update', function () {
var action = $("#slct_bulk_update").val();
var $data_table = $("#idc_assets_table").DataTable();
var id_list = [];
var plain_id_list = [];
var assets = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
$.ajax({
url: '{% url "api-assets:asset-list" %}',
data: {"idc_id": {{ idc.id }}},
dataType: 'json',
method: 'GET',
success: function (result) {
for (var i in result) {
if (!isNaN(result[i]['id'])) {
assets.push(result[i]['id']);
}
}
for (var j in plain_id_list) {
assets.remove(plain_id_list[j])
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#idc_assets_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
APIUpdateAttr({url: url_delete, body: JSON.stringify(body), method: 'PUT', success: success, error: fail});
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}
});
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.users != undefined) {
body.users = json_data.users;
}
if (typeof body.users === 'string') {
body.users = [parseInt(body.users)]
} else if(typeof body.users === 'array') {
var new_users = body.users.map(Number);
body.users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
}); });
</script> if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_bulk_update_modal').modal('hide');
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a> <a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a>
</li> </li>
<li class="pull-right"> <li class="pull-right">
<a class="btn btn-outline btn-danger" href="{% url 'assets:idc-delete' pk=idc.id %}"> <a class="btn btn-outline btn-danger btn-delete-idc">
<i class="fa fa-edit"></i>Delete <i class="fa fa-edit"></i>Delete
</a> </a>
</li> </li>
...@@ -53,9 +53,9 @@ ...@@ -53,9 +53,9 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table"> <table class="table idc-details">
<tbody> <tbody>
<tr class="no-borders-tr"> <tr class="no-borders-tr" data-name="{{ idc.name }}">
<td>{% trans 'Name' %}:</td> <td>{% trans 'Name' %}:</td>
<td><b>{{ idc.name }}</b></td> <td><b>{{ idc.name }}</b></td>
</tr> </tr>
...@@ -113,26 +113,47 @@ ...@@ -113,26 +113,47 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} function idcDelete(name, url) {
{# var status = $(obj).prop('checked');#} function doDelete() {
{##} var body = {};
{# $.ajax({#} var success = function() {
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
{# type: "PUT",#} window.location.href="{% url 'assets:idc-list' %}";
{# data: {#} };
{# 'is_active': status#} var fail = function() {
{# },#} swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
{# success: function (data, status) {#} };
{# console.log(data)#} APIUpdateAttr({
{# },#} url: url,
{# error: function () {#} body: JSON.stringify(body),
{# console.log('error')#} method: 'DELETE',
{# }#} success: success,
{# })#} error: fail
{# }#} });
$(document).ready(function () { }
$('.select2').select2(); swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
}); });
</script> }
$(document).ready(function () {
$('.select2').select2();
})
.on('click', '.btn-delete-idc', function () {
var name = $('.idc-details > tbody > tr').attr("data-name");
var id = {{ idc.id }};
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace(99991937, id);
idcDelete(name, the_url);
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
{% extends '_base_list.html' %} {% extends '_base_list.html' %}
{% load i18n static %} {% load i18n static %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %}
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
<div class="uc pull-left m-l-5 m-r-5"> <div class="uc pull-left m-l-5 m-r-5">
...@@ -22,6 +26,18 @@ ...@@ -22,6 +26,18 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
...@@ -34,20 +50,10 @@ $(document).ready(function(){ ...@@ -34,20 +50,10 @@ $(document).ready(function(){
var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:idc-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) {#}
{# var innerHtml = cellData.length > 8 ? cellData.substring(0, 8) + '...': cellData;#}
{# $(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');#}
{# }},#}
{# {targets: 6, createdCell: function (td, cellData) {#}
{# if (!cellData) {#}
{# $(td).html('<i class="fa fa-times text-danger"></i>')#}
{# } else {#}
{# $(td).html('<i class="fa fa-check text-navy"></i>')#}
{# }#}
{# }},#}
{targets: 6, createdCell: function (td, cellData, rowData) { {targets: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData); var update_btn = '<a href="{% url "assets:idc-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_idc_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}}], }}],
ajax_url: '{% url "api-assets:idc-list" %}', ajax_url: '{% url "api-assets:idc-list" %}',
...@@ -56,6 +62,64 @@ $(document).ready(function(){ ...@@ -56,6 +62,64 @@ $(document).ready(function(){
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_idc_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
{# TODO: reload the tale #}
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#idc_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:idc-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected idc !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'IDC Deleted.' %}";
swal("{% trans 'IDC Delete' %}", msg, "success");
$('#idc_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'IDC Deleting failed.' %}";
swal("{% trans 'IDC Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
switch (action) {
case 'delete':
doDelete();
break;
default:
break;
}
}); });
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -43,35 +43,35 @@ ...@@ -43,35 +43,35 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-hover"> <table class="table table-hover" id="system_user_list">
<thead> <thead>
<tr> <tr>
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Reachable' %}</th> <th>{% trans 'Reachable' %}</th>
<th></th> <th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in page_obj %} {# {% for asset in page_obj %}#}
<tr> {# <tr>#}
<td>{{ asset.hostname }}</td> {# <td>{{ asset.hostname }}</td>#}
<td>{{ asset.ip }}</td> {# <td>{{ asset.ip }}</td>#}
<td>{{ asset.port }}</td> {# <td>{{ asset.port }}</td>#}
<td> {# <td>#}
<i class="fa fa-check text-navy"></i> {# <i class="fa fa-check text-navy"></i>#}
</td> {# </td>#}
<td> {# <td>#}
<button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button> {# <button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button>#}
</td> {# </td>#}
</tr> {# </tr>#}
{% endfor %} {# {% endfor %}#}
</tbody> </tbody>
</table> </table>
<div class="row"> {# <div class="row">#}
{% include '_pagination.html' %} {# {% include '_pagination.html' %}#}
</div> {# </div>#}
</div> </div>
</div> </div>
</div> </div>
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Attach' %}</button> <button type="button" class="btn btn-primary btn-sm btn-add-asset2system-user">{% trans 'Attach Asset' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
...@@ -123,16 +123,16 @@ ...@@ -123,16 +123,16 @@
</tr> </tr>
<tr> <tr>
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Attach' %}</button> <button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Attach AssetGroup' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for asset_group in asset_groups %} {% for asset_group in asset_groups %}
<tr> <tr>
<td ><b data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td> <td ><b class="bdg_asset_groups" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
<td> <td>
<button class="btn btn-danger pull-right btn-xs" type="button"><i class="fa fa-minus"></i></button> <button class="btn btn-danger pull-right btn-xs btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
...@@ -150,26 +150,224 @@ ...@@ -150,26 +150,224 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} jumpserver.assets_selected = {};
{# var status = $(obj).prop('checked');#} jumpserver.asset_groups_selected = {};
{##} Array.prototype.remove = function(val) {
{# $.ajax({#} var index = this.indexOf(val);
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} if (index > -1) {
{# type: "PUT",#} this.splice(index, 1);
{# data: {#} }
{# 'is_active': status#} };
{# },#} Array.prototype.unique = function(){
{# success: function (data, status) {#} var res = [];
{# console.log(data)#} var json = {};
{# },#} for(var i = 0; i < this.length; i++){
{# error: function () {#} if(!json[this[i]]){
{# console.log('error')#} res.push(this[i]);
{# }#} json[this[i]] = 1;
{# })#} }
{# }#} }
$(document).ready(function () { return res;
$('.select2').select2(); };
function objectDelete(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
function updateSystemUserAssetGroup(asset_groups) {
var the_url = "{% url 'api-assets:systemuser-update-assetgroups' pk=system_user.id %}";
var body = {
asset_groups: Object.assign([], asset_groups)
};
var success = function(data) {
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.asset_groups_selected, function(asset_groups, index) {
$('#opt_' + index).remove();
$('.system-user-table tbody').append(
'<tr>' +
'<td><b class="bdg_asset_groups" data-sid="' + index + '">' + asset_groups + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
jumpserver.assets_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.asset_groups_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.asset_groups_selected[data.id];
});
var options = {
ele: $('#system_user_list'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" }, {data: function () { return ""; } }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-add-asset2system-user', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var $data_table = $("#system_user_list").DataTable();
var assets = [];
$.ajax({
url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
method: 'GET',
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
var body = {"assets": assets};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
$data_table.ajax.reload();
}
});
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var $data_table = $("#system_user_list").DataTable();
var assets = [];
$('#system_user_list > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
assets.unique();
var data = {"assets": assets};
objectDelete($this, name, the_url, data);
$data_table.ajax.reload();
})
.on('click', '#btn_add_user_group', function () {
jumpserver.assets_selected = {};
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
return false;
}
asset_groups = [];
$.ajax({
url: '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}',
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i in result['asset_groups']) {
if (!isNaN(result['asset_groups'][i])) {
asset_groups.push(parseInt(result['asset_groups'][i]));
}
}
$.map(jumpserver.asset_groups_selected, function(value, index) {
asset_groups.push(parseInt(index));
}); });
</script> asset_groups.unique();
console.log(asset_groups);
var the_url = '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}';
var body = {"asset_groups": asset_groups};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
{# TODO: reload the table #}
{# window.location.href="{% url 'assets:system-user-asset' pk=system_user.id %}"#}
}
});
})
.on('click', '.btn-leave-system_user', function () {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_asset_groups');
var sid = $badge.data('gid');
var name = $badge.html() || $badge.text();
$('system-user-table').append(
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
);
$tr.remove();
var asset_groups = $('.bdg_asset_groups').map(function () {
return $(this).data('gid');
}).get();
updateSystemUserAssetGroup(asset_groups);
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -26,10 +26,23 @@ ...@@ -26,10 +26,23 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
var options = { var options = {
ele: $('#system_user_list_table'), ele: $('#system_user_list_table'),
columnDefs: [ columnDefs: [
...@@ -50,9 +63,73 @@ ...@@ -50,9 +63,73 @@
ajax_url: '{% url "api-assets:system-user-list" %}', ajax_url: '{% url "api-assets:system-user-list" %}',
columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}}, columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}},
{data: "comment" }, {data: "id" }], {data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#system_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:system-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected System Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'System Users Deleted.' %}";
swal("{% trans 'System Users Delete' %}", msg, "success");
$('#system_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'System Users Deleting failed.' %}";
swal("{% trans 'System Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
}); });
}
function doUpdate() {
{# TODO: bulk update the System Users #}
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -2,16 +2,18 @@ ...@@ -2,16 +2,18 @@
from django.conf.urls import url from django.conf.urls import url
from .. import api from .. import api
from rest_framework import routers from rest_framework import routers
from rest_framework_bulk.routes import BulkRouter
app_name = 'assets' app_name = 'assets'
router = routers.DefaultRouter() router = BulkRouter()
router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group') router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group')
router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/assets', api.AssetViewSet, 'asset')
router.register(r'v1/idc', api.IDCViewSet, 'idc') router.register(r'v1/idc', api.IDCViewSet, 'idc')
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
router.register(r'v1/tags', api.TagViewSet, 'asset-tag')
urlpatterns = [ urlpatterns = [
url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
...@@ -20,8 +22,31 @@ urlpatterns = [ ...@@ -20,8 +22,31 @@ urlpatterns = [
url(r'^v1/assets/(?P<pk>\d+)/groups/$', url(r'^v1/assets/(?P<pk>\d+)/groups/$',
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'), api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
url(r'^v1/assets/(?P<pk>\d+)/system-users/$', url(r'^v1/assets/(?P<pk>\d+)/system-users/$',
api.SystemUserUpdateApi.as_view(), name='asset-update-systemusers'), api.SystemUserUpdateApi.as_view(), name='asset-update-systemusers'),
## update the system users, which add and delete the asset to the system user
url(r'^v1/system_user/(?P<pk>\d+)/assets/$',
api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'),
url(r'^v1/system_user/(?P<pk>\d+)/groups/$',
api.SystemUserUpdateAssetGroupApi.as_view(), name='systemuser-update-assetgroups'),
## update the asset group, which add or delete the asset to the group
url(r'^v1/groups/(?P<pk>\d+)/assets/$',
api.AssetGroupUpdateApi.as_view(), name='asset-groups-update'),
## update the asset group, and add or delete the system_user to the group
url(r'^v1/groups/(?P<pk>\d+)/system-users/$',
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
## update the IDC, and add or delete the assets to the IDC
url(r'^v1/idc/(?P<pk>\d+)/assets/$',
api.IDCupdateAssetsApi.as_view(), name='idc-update-assets'),
url(r'v1/tag/(?P<pk>\d+)/assets/$',
api.TagUpdateAssetsApi.as_view(), name='tag-update-assets'),
] ]
urlpatterns += router.urls urlpatterns += router.urls
......
...@@ -16,7 +16,7 @@ from django.urls import reverse_lazy ...@@ -16,7 +16,7 @@ from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.detail import DetailView, SingleObjectMixin
from django.shortcuts import get_object_or_404, reverse, redirect from django.shortcuts import get_object_or_404, reverse, redirect
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_protect, csrf_exempt from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.core.cache import cache from django.core.cache import cache
...@@ -37,8 +37,10 @@ class AssetListView(AdminUserRequiredMixin, TemplateView): ...@@ -37,8 +37,10 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'asset list', 'action': 'asset list',
'tag_list': [(i.id, i.name, i.asset_set.all().count())for i in Tag.objects.all().order_by('name')] 'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'tag_list': [(i.id, i.name, i.assets.all().count())for i in Tag.objects.all().order_by('name')],
'tags': Tag.objects.all().order_by('name')
} }
kwargs.update(context) kwargs.update(context)
return super(AssetListView, self).get_context_data(**kwargs) return super(AssetListView, self).get_context_data(**kwargs)
...@@ -261,6 +263,8 @@ class AssetGroupListView(AdminUserRequiredMixin, TemplateView): ...@@ -261,6 +263,8 @@ class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Asset group list'), 'action': _('Asset group list'),
'assets': Asset.objects.all(),
'system_users': SystemUser.objects.all(),
'keyword': self.request.GET.get('keyword', '') 'keyword': self.request.GET.get('keyword', '')
} }
kwargs.update(context) kwargs.update(context)
...@@ -280,6 +284,7 @@ class AssetGroupDetailView(AdminUserRequiredMixin, DetailView): ...@@ -280,6 +284,7 @@ class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
'app': _('Assets'), 'app': _('Assets'),
'action': _('Asset group detail'), 'action': _('Asset group detail'),
'assets_remain': assets_remain, 'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
'system_users': system_users, 'system_users': system_users,
'system_users_remain': system_users_remain, 'system_users_remain': system_users_remain,
} }
...@@ -383,6 +388,22 @@ class IDCAssetsView(AdminUserRequiredMixin, DetailView): ...@@ -383,6 +388,22 @@ class IDCAssetsView(AdminUserRequiredMixin, DetailView):
template_name = 'assets/idc_assets.html' template_name = 'assets/idc_assets.html'
context_object_name = 'idc' context_object_name = 'idc'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'tags': Tag.objects.all(),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
}
kwargs.update(context)
return super(IDCAssetsView, self).get_context_data(**kwargs)
class IDCDeleteView(AdminUserRequiredMixin, DeleteView): class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
model = IDC model = IDC
...@@ -477,10 +498,19 @@ class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView): ...@@ -477,10 +498,19 @@ class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
def get_queryset(self): def get_queryset(self):
return self.object.assets.all() return self.object.assets.all()
# def get_asset_groups(self):
# return self.object.asset_groups.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
asset_groups = AssetGroup.objects.all()
assets = self.get_queryset()
context = { context = {
'app': 'assets', 'app': 'assets',
'action': 'Admin user detail' 'action': 'Admin user detail',
'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets],
'asset_groups': asset_groups,
# 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
# if asset_group not in asset_groups]
} }
kwargs.update(context) kwargs.update(context)
return super(AdminUserDetailView, self).get_context_data(**kwargs) return super(AdminUserDetailView, self).get_context_data(**kwargs)
...@@ -630,7 +660,7 @@ class TagsListView(AdminUserRequiredMixin, ListView): ...@@ -630,7 +660,7 @@ class TagsListView(AdminUserRequiredMixin, ListView):
return super(TagsListView, self).get_context_data(**kwargs) return super(TagsListView, self).get_context_data(**kwargs)
class AssetTagCreateView(AdminUserRequiredMixin, CreateView): class AssetTagCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
model = Tag model = Tag
form_class = forms.AssetTagForm form_class = forms.AssetTagForm
template_name = 'assets/asset_tag_create.html' template_name = 'assets/asset_tag_create.html'
...@@ -653,7 +683,7 @@ class AssetTagCreateView(AdminUserRequiredMixin, CreateView): ...@@ -653,7 +683,7 @@ class AssetTagCreateView(AdminUserRequiredMixin, CreateView):
assets_id_list = self.request.POST.getlist('assets', []) assets_id_list = self.request.POST.getlist('assets', [])
assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list] assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list]
asset_tag.created_by = self.request.user.username or 'Admin' asset_tag.created_by = self.request.user.username or 'Admin'
asset_tag.asset_set.add(*tuple(assets)) asset_tag.assets.add(*tuple(assets))
asset_tag.save() asset_tag.save()
return super(AssetTagCreateView, self).form_valid(form) return super(AssetTagCreateView, self).form_valid(form)
...@@ -662,18 +692,22 @@ class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView): ...@@ -662,18 +692,22 @@ class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView):
template_name = 'assets/asset_tag_detail.html' template_name = 'assets/asset_tag_detail.html'
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=Tag.objects.all()) self.object = self.get_object(queryset=Tag.objects.all())
return super(AssetTagDetailView, self).get(request, *args, **kwargs) return super(AssetTagDetailView, self).get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return self.object.asset_set.all() return self.object.assets.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags detail'), 'action': _('Asset Tags detail'),
'asset_tag': self.object, 'asset_tag': self.object,
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain]
} }
kwargs.update(context) kwargs.update(context)
return super(AssetTagDetailView, self).get_context_data(**kwargs) return super(AssetTagDetailView, self).get_context_data(**kwargs)
...@@ -690,7 +724,7 @@ class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -690,7 +724,7 @@ class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView):
return super(AssetTagUpdateView, self).get(request, *args, **kwargs) return super(AssetTagUpdateView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_all = self.object.asset_set.all() assets_all = self.object.assets.all()
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags detail'), 'action': _('Asset Tags detail'),
...@@ -713,9 +747,9 @@ class AssetExportView(View): ...@@ -713,9 +747,9 @@ class AssetExportView(View):
@staticmethod @staticmethod
def get_asset_attr(asset, attr): def get_asset_attr(asset, attr):
if attr in ['admin_user', 'idc']: if attr in ['admin_user', 'idc']:
return getattr(asset, attr).name return getattr(asset, attr)
elif attr in ['status', 'type', 'env']: # elif attr in ['status', 'type', 'env']:
return getattr(asset, 'get_{}_display'.format(attr))() # return getattr(asset, 'get_{}_display'.format(attr))
else: else:
return getattr(asset, attr) return getattr(asset, attr)
...@@ -735,8 +769,10 @@ class AssetExportView(View): ...@@ -735,8 +769,10 @@ class AssetExportView(View):
ws.append(header) ws.append(header)
for asset in assets: for asset in assets:
print [self.get_asset_attr(asset, attr) for attr in header]
ws.append([self.get_asset_attr(asset, attr) for attr in header]) ws.append([self.get_asset_attr(asset, attr) for attr in header])
filename = 'assets-{}.xlsx'.format(timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S')) filename = 'assets-{}.xlsx'.format(timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel') response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename response['Content-Disposition'] = 'attachment; filename="%s"' % filename
...@@ -745,13 +781,13 @@ class AssetExportView(View): ...@@ -745,13 +781,13 @@ class AssetExportView(View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
try: try:
assets_id = json.loads(request.body).get('assets_id', []) assets_id = json.loads(request.body).get('assets_id', [])
print(assets_id)
except ValueError: except ValueError:
return HttpResponse('Json object not valid', status=400) return HttpResponse('Json object not valid', status=400)
spm = uuid.uuid4().get_hex() spm = uuid.uuid4().get_hex()
cache.set(spm, assets_id, 300) cache.set(spm, assets_id, 300)
url = reverse('assets:asset-export') + '?spm=%s' % spm url = reverse('assets:asset-export') + '?spm=%s' % spm
return JsonResponse({'redirect': url}) print url
return HttpResponse({'redirect': url})
class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
......
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 to comment