[Update] 修复页面bug和popover的问题 (#3219)

* [Update] 修复页面bug和popover的问题

* [Update] 修改asset modal table

* [Update] 修改翻译

* [Update] 修改id cache api mixin

* [Update] 去掉asset permission中不用的代码
pull/3224/head
老广 2019-09-12 18:18:34 +08:00 committed by GitHub
commit 3a8fad7c7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 696 additions and 666 deletions

View File

@ -33,11 +33,16 @@ class AssetCreateForm(OrgModelForm):
return return
nodes_field = self.fields['nodes'] nodes_field = self.fields['nodes']
if self.instance: if self.instance:
nodes_field.choices = ((n.id, n.full_value) for n in nodes_field.choices = [(n.id, n.full_value) for n in
self.instance.nodes.all()) self.instance.nodes.all()]
else: else:
nodes_field.choices = [] nodes_field.choices = []
def add_nodes_initial(self, node):
nodes_field = self.fields['nodes']
nodes_field.choices.append((node.id, node.full_value))
nodes_field.initial = [node]
class Meta: class Meta:
model = Asset model = Asset
fields = [ fields = [

View File

@ -37,19 +37,22 @@ class TreeMixin:
def tree(cls): def tree(cls):
from ..utils import TreeService from ..utils import TreeService
tree_updated_time = cache.get(cls.tree_updated_time_cache_key, 0) tree_updated_time = cache.get(cls.tree_updated_time_cache_key, 0)
now = time.time()
# 什么时候重新初始化 _tree_service
if not cls.tree_created_time or \ if not cls.tree_created_time or \
tree_updated_time > cls.tree_created_time: tree_updated_time > cls.tree_created_time:
logger.debug("Create node tree") logger.debug("Create node tree")
tree = TreeService.new() tree = TreeService.new()
cls.tree_created_time = time.time() cls.tree_created_time = now
cls.tree_assets_created_time = time.time() cls.tree_assets_created_time = now
cls._tree_service = tree cls._tree_service = tree
return tree return tree
# 是否要重新初始化节点资产
node_assets_updated_time = cache.get(cls.tree_assets_cache_key, 0) node_assets_updated_time = cache.get(cls.tree_assets_cache_key, 0)
if not cls.tree_assets_created_time or \ if not cls.tree_assets_created_time or \
node_assets_updated_time > cls.tree_assets_created_time: node_assets_updated_time > cls.tree_assets_created_time:
cls._tree_service.init_assets_async() cls._tree_service.init_assets()
cls.tree_assets_created_time = time.time() cls.tree_assets_created_time = now
logger.debug("Refresh node tree assets") logger.debug("Refresh node tree assets")
return cls._tree_service return cls._tree_service

View File

@ -15,11 +15,11 @@
text-align: center; text-align: center;
} }
#assetTree2.ztree * { #asset_modal_tree.ztree * {
background-color: #f8fafb; background-color: white;
} }
#assetTree2.ztree { #asset_modal_tree.ztree {
background-color: #f8fafb; background-color: white;
} }
</style> </style>
@ -29,7 +29,8 @@
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px"> <div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
<div class="file-manager "> <div class="file-manager ">
<div id="assetTree2" class="ztree"> <div id="asset_modal_tree" class="ztree">
{% trans 'Loading' %} ...
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
@ -55,12 +56,77 @@
</div> </div>
<script> <script>
var zTree2, asset_table2 = 0; function syncTableSelectedAssetToSelect2(table) {
function initTable2() { var assets = table.selected;
if(asset_table2){ var options = [];
return var select2Id = assetModalOption.select2Id;
$(select2Id + ' option').each(function (i, v) {
options.push(v.value)
});
table.selected_rows.forEach(function (i) {
var name = i.hostname + '(' + i.ip + ')';
var option = new Option(name, i.id, false, true);
if (options.indexOf(i.id) === -1) {
$(select2Id).append(option).trigger('change');
}
});
$(select2Id).val(assets).trigger('change');
}
// 解决input框中的资产和弹出表格中资产的显示不一致
function syncSelectedAssetsToModalTable(assetModalTable) {
var select2Id = assetModalOption.select2Id;
var inputAssets = $(select2Id).val();
var selectedAssets = assetModalTable.selected.concat();
// input assets无table assets选中则取消勾选(再次click)
if (selectedAssets.length !== 0) {
$.each(selectedAssets, function (index, assetId) {
if ($.inArray(assetId, inputAssets) === -1) {
$('#' + assetId).trigger('click'); // 取消勾选
}
});
} }
// input assets有table assets没选则选中(click)
if (inputAssets !== null) {
assetModalTable.selected = inputAssets;
$.each(inputAssets, function (index, assetId) {
var dom = document.getElementById(assetId);
if (dom !== null) {
var selected = dom.parentElement.parentElement.className.indexOf('selected')
}
if (selected === -1) {
$('#' + assetId).trigger('click');
}
});
}
}
defaultOnAssetModalConfirm = syncTableSelectedAssetToSelect2;
defaultOnModalTableDone = syncSelectedAssetsToModalTable;
var assetModalOption = {
selectStyle: 'multi',
select2Id: '#id_assets',
onModalTableDone: defaultOnModalTableDone,
onModalTreeDone: null,
onModalConfirm: defaultOnAssetModalConfirm,
};
var assetModalTable, assetModalTree = null;
function initAssetModalTable() {
if(assetModalTable){
return
}
if (assetModalOption.selectStyle === 'single') {
$('.ipt_check_all').addClass('hidden')
}
var options = { var options = {
ele: $('#asset_list_modal_table'), ele: $('#asset_list_modal_table'),
ajax_url: '{% url "api-assets:asset-list" %}?show_current_asset=1', ajax_url: '{% url "api-assets:asset-list" %}?show_current_asset=1',
@ -68,22 +134,26 @@ function initTable2() {
{data: "id"}, {data: "hostname" }, {data: "ip" } {data: "id"}, {data: "hostname" }, {data: "ip" }
], ],
lengthMenu: [[10, 25, 50], [10, 25, 50]], lengthMenu: [[10, 25, 50], [10, 25, 50]],
pageLength: 10 pageLength: 10,
select_style: assetModalOption.selectStyle
}; };
asset_table2 = jumpserver.initServerSideDataTable(options); assetModalTable = jumpserver.initServerSideDataTable(options);
return asset_table2 if (assetModalOption.onModalTableDone) {
assetModalOption.onModalTableDone(assetModalTable);
}
return assetModalTable
} }
function onNodeSelected2(event, treeNode) { function onModalTreeNodeSelected(event, treeNode) {
var url = asset_table2.ajax.url(); var url = assetModalTable.ajax.url();
url = setUrlParam(url, "node_id", treeNode.meta.node.id); url = setUrlParam(url, "node_id", treeNode.meta.node.id);
url = setUrlParam(url, "show_current_asset", ""); url = setUrlParam(url, "show_current_asset", "");
asset_table2.ajax.url(url); assetModalTable.ajax.url(url);
asset_table2.ajax.reload(); assetModalTable.ajax.reload();
} }
function initTree2() { function initModalTree() {
var url = '{% url 'api-assets:node-children-tree' %}?assets=0'; var url = '{% url 'api-assets:node-children-tree' %}?assets=0';
var setting = { var setting = {
view: { view: {
@ -102,17 +172,34 @@ function initTree2() {
type: 'get' type: 'get'
}, },
callback: { callback: {
onSelected: onNodeSelected2 onSelected: onModalTreeNodeSelected
} }
}; };
zTree2 = $.fn.zTree.init($("#assetTree2"), setting); $.get(url, function(data, status){
$.fn.zTree.init($("#asset_modal_tree"), setting);
assetModalTree = $.fn.zTree.getZTreeObj("assetTree2");
if (assetModalOption.onModalTreeDone) {
assetModalOption.onModalTreeDone(assetModalTree);
}
return assetModalTree;
});
}
function setAssetModalOptions(options) {
assetModalOption = options;
} }
$(document).ready(function(){ $(document).ready(function(){
}).on('show.bs.modal', function () { }).on('show.bs.modal', function () {
initTable2(); initAssetModalTable();
initTree2(); initModalTree();
}).on('click', '#btn_asset_modal_confirm', function () {
if (assetModalOption.onModalConfirm) {
assetModalOption.onModalConfirm(assetModalTable, assetModalTree);
}
$("#asset_list_modal").modal('hide');
}) })
</script> </script>
{% endblock %} {% endblock %}

View File

@ -226,6 +226,33 @@ function onNodeSelected(event, treeNode) {
asset_table.ajax.reload(); asset_table.ajax.reload();
} }
function onAssetModalConfirmAddAssetToNode(table) {
var assets_selected = table.selected;
if (!current_node_id) {
return
}
var data = {'assets': assets_selected};
var success = function () {
table.selected = [];
table.ajax.reload()
};
var url = '';
if (update_node_action === "move") {
url = "{% url 'api-assets:node-replace-assets' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node_id);
} else {
url = "{% url 'api-assets:node-add-assets' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node_id);
}
requestApi({
'url': url,
'method': 'PUT',
'body': JSON.stringify(data),
'success': success
})
}
$(document).ready(function(){ $(document).ready(function(){
initTable(); initTable();
initTree(); initTree();
@ -236,6 +263,12 @@ $(document).ready(function(){
else{ else{
$('#show_current_asset').css('display', 'inline-block'); $('#show_current_asset').css('display', 'inline-block');
} }
var modalOption = {
onModalConfirm: onAssetModalConfirmAddAssetToNode,
onModalTableDone: null
};
setAssetModalOptions(modalOption);
}) })
.on('click', '.labels li', function () { .on('click', '.labels li', function () {
var val = $(this).text(); var val = $(this).text();
@ -429,7 +462,6 @@ $(document).ready(function(){
} }
function doRemove() { function doRemove() {
var nodes = zTree.getSelectedNodes();
if (!current_node_id) { if (!current_node_id) {
return return
} }
@ -472,32 +504,7 @@ $(document).ready(function(){
} }
$(".ipt_check_all").prop("checked", false) $(".ipt_check_all").prop("checked", false)
}) })
.on('click', '#btn_asset_modal_confirm', function () { .on('hidden.bs.modal', '#asset_list_modal', function () {
var assets_selected = asset_table2.selected;
if (!current_node_id) {
return
}
var data = {'assets': assets_selected};
var success = function () {
asset_table2.selected = [];
asset_table2.ajax.reload()
};
var url = '';
if (update_node_action === "move") {
url = "{% url 'api-assets:node-replace-assets' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node_id);
} else {
url = "{% url 'api-assets:node-add-assets' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node_id);
}
requestApi({
'url': url,
'method': 'PUT',
'body': JSON.stringify(data),
'success': success
})
}).on('hidden.bs.modal', '#asset_list_modal', function () {
window.location.reload(); window.location.reload();
}).on('click', '#menu_asset_add', function () { }).on('click', '#menu_asset_add', function () {
update_node_action = "add" update_node_action = "add"

View File

@ -28,25 +28,6 @@ $(document).ready(function () {
}).on('click', '.select2-selection__rendered', function (e) { }).on('click', '.select2-selection__rendered', function (e) {
e.preventDefault(); e.preventDefault();
$("#asset_list_modal").modal(); $("#asset_list_modal").modal();
initSelectedAssets2Table();
})
.on('click', '#btn_asset_modal_confirm', function () {
var assets = asset_table2.selected;
var options = [];
$('#id_assets option').each(function (i, v) {
options.push(v.value)
});
asset_table2.selected_rows.forEach(function (i) {
var name = i.hostname + '(' + i.ip + ')';
var option = new Option(name, i.id, false, true);
if (options.indexOf(i.id) === -1) {
$('#id_assets').append(option).trigger('change');
}
});
$('.select2').val(assets).trigger('change');
$("#asset_list_modal").modal('hide');
}) })
.on("submit", "form", function (evt) { .on("submit", "form", function (evt) {
evt.preventDefault(); evt.preventDefault();

View File

@ -32,24 +32,6 @@ $(document).ready(function () {
}).on('click', '.select2-selection__rendered', function (e) { }).on('click', '.select2-selection__rendered', function (e) {
e.preventDefault(); e.preventDefault();
$("#asset_list_modal").modal(); $("#asset_list_modal").modal();
initSelectedAssets2Table();
})
.on('click', '#btn_asset_modal_confirm', function () {
var assets = asset_table2.selected;
var options = [];
$('#id_assets option').each(function (i, v) {
options.push(v.value)
});
asset_table2.selected_rows.forEach(function (i) {
var name = i.hostname + '(' + i.ip + ')';
var option = new Option(name, i.id, false, true);
if (options.indexOf(i.id) === -1) {
$('#id_assets').append(option).trigger('change');
}
});
$('#id_assets').val(assets).trigger('change');
$("#asset_list_modal").modal('hide');
}) })
.on("submit", "form", function (evt) { .on("submit", "form", function (evt) {
evt.preventDefault(); evt.preventDefault();

View File

@ -86,7 +86,7 @@ class AssetCreateView(PermissionsMixin, FormMixin, TemplateView):
node = get_object_or_none(Node, id=node_id) node = get_object_or_none(Node, id=node_id)
else: else:
node = Node.org_root() node = Node.org_root()
form["nodes"].initial = node form.add_nodes_initial(node)
return form return form
def get_protocol_formset(self): def get_protocol_formset(self):

View File

@ -11,6 +11,9 @@
#search_btn { #search_btn {
margin-bottom: 0; margin-bottom: 0;
} }
.form-control {
height: 30px;
}
</style> </style>
{% endblock %} {% endblock %}

View File

@ -8,6 +8,12 @@
#search_btn { #search_btn {
margin-bottom: 0; margin-bottom: 0;
} }
.form-control {
height: 30px;
}
.select2-selection__rendered span.select2-selection, .select2-container .select2-selection--single {
height: 30px !important;
}
</style> </style>
{% endblock %} {% endblock %}

View File

@ -11,6 +11,12 @@
#search_btn { #search_btn {
margin-bottom: 0; margin-bottom: 0;
} }
.form-control {
height: 30px;
}
.select2-selection__rendered span.select2-selection, .select2-container .select2-selection--single {
height: 30px !important;
}
</style> </style>
{% endblock %} {% endblock %}

View File

@ -11,6 +11,12 @@
#search_btn { #search_btn {
margin-bottom: 0; margin-bottom: 0;
} }
.form-control {
height: 30px;
}
.select2-selection__rendered span.select2-selection, .select2-container .select2-selection--single {
height: 30px !important;
}
</style> </style>
{% endblock %} {% endblock %}

View File

@ -44,7 +44,9 @@ class IDInCacheFilterMixin(object):
return queryset return queryset
cache_key = KEY_CACHE_RESOURCES_ID.format(spm) cache_key = KEY_CACHE_RESOURCES_ID.format(spm)
resources_id = cache.get(cache_key) resources_id = cache.get(cache_key)
if resources_id and isinstance(resources_id, list): if not resources_id or not isinstance(resources_id, list):
queryset = queryset.none()
return queryset
queryset = queryset.filter(id__in=resources_id) queryset = queryset.filter(id__in=resources_id)
return queryset return queryset

View File

@ -14,7 +14,7 @@ from .local import thread_local
pattern = re.compile(r'FROM `(\w+)`') pattern = re.compile(r'FROM `(\w+)`')
logger = get_logger(__name__) logger = get_logger(__name__)
DEBUG_DB_QUERY = os.environ.get('DEBUG_DB_QUERY', '0') == '1' DEBUG_DB = os.environ.get('DEBUG_DB', '0') == '1'
class Counter: class Counter:
@ -58,7 +58,7 @@ def on_request_finished_release_local(sender, **kwargs):
thread_local.__release_local__() thread_local.__release_local__()
if settings.DEBUG and DEBUG_DB_QUERY: if settings.DEBUG and DEBUG_DB:
request_finished.connect(on_request_finished_logging_db_query) request_finished.connect(on_request_finished_logging_db_query)

View File

@ -609,6 +609,7 @@ SWAGGER_SETTINGS = {
}, },
} }
# Default email suffix # Default email suffix
EMAIL_SUFFIX = CONFIG.EMAIL_SUFFIX EMAIL_SUFFIX = CONFIG.EMAIL_SUFFIX
LOGIN_LOG_KEEP_DAYS = CONFIG.LOGIN_LOG_KEEP_DAYS LOGIN_LOG_KEEP_DAYS = CONFIG.LOGIN_LOG_KEEP_DAYS

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ def run_ansible_task(tid, callback=None, **kwargs):
logger.error("No task found") logger.error("No task found")
@shared_task(soft_time_limit=60) @shared_task(soft_time_limit=60, queue="ansible")
def run_command_execution(cid, **kwargs): def run_command_execution(cid, **kwargs):
execution = get_object_or_none(CommandExecution, id=cid) execution = get_object_or_none(CommandExecution, id=cid)
if execution: if execution:

View File

@ -9,6 +9,9 @@
<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> <style>
.form-control {
height: 30px;
}
#search_btn { #search_btn {
margin-bottom: 0; margin-bottom: 0;
@ -88,13 +91,6 @@
<script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script> <script src="{% static "js/plugins/footable/footable.all.min.js" %}"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
{#$('table').DataTable({#}
{# "searching": false,#}
{# "paging": false,#}
{# "bInfo" : false,#}
{# "order": []#}
{# });#}
{#$('.footable').footable();#}
$('.select2').select2({ $('.select2').select2({
dropdownAutoWidth : true, dropdownAutoWidth : true,
width: 'auto' width: 'auto'
@ -116,7 +112,14 @@ $(document).ready(function() {
var html = createPopover(data_list); var html = createPopover(data_list);
$(this).html(html); $(this).html(html);
}); });
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover({
html: true,
placement: 'bottom',
trigger: 'click',
container: 'body'
}).on('click', function (e) {
$('[data-toggle="popover"]').not(this).popover('hide');
});
}) })
</script> </script>
{% endblock %} {% endblock %}

View File

@ -35,6 +35,10 @@ class OrgBulkModelViewSet(IDInCacheFilterMixin, BulkModelViewSet):
return queryset return queryset
def allow_bulk_destroy(self, qs, filtered): def allow_bulk_destroy(self, qs, filtered):
if qs.count() <= filtered.count():
return False
if self.request.query_params.get('spm', ''):
return True
return False return False

View File

@ -97,6 +97,8 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
inherit_nodes_keys = assets.all().values_list('nodes__key', flat=True) inherit_nodes_keys = assets.all().values_list('nodes__key', flat=True)
for key in inherit_nodes_keys: for key in inherit_nodes_keys:
if key is None:
continue
ancestor_keys = Node.get_nodes_ancestor_keys_by_key(key, with_self=True) ancestor_keys = Node.get_nodes_ancestor_keys_by_key(key, with_self=True)
inherit_all_nodes.update(ancestor_keys) inherit_all_nodes.update(ancestor_keys)
queryset = queryset.filter( queryset = queryset.filter(

View File

@ -53,6 +53,16 @@ class AssetPermissionForm(OrgModelForm):
assets_field.queryset = Asset.objects.none() assets_field.queryset = Asset.objects.none()
nodes_field.queryset = Node.objects.none() nodes_field.queryset = Node.objects.none()
def set_nodes_initial(self, nodes):
field = self.fields['nodes']
field.choices = [(n.id, n.full_value) for n in nodes]
field.initial = nodes
def set_assets_initial(self, assets):
field = self.fields['assets']
field.choices = [(a.id, a.hostname) for a in assets]
field.initial = assets
class Meta: class Meta:
model = AssetPermission model = AssetPermission
exclude = ( exclude = (

View File

@ -47,7 +47,7 @@ def on_permission_nodes_changed(sender, instance=None, action='', **kwargs):
if isinstance(instance, AssetPermission): if isinstance(instance, AssetPermission):
logger.debug("Asset permission nodes change signal received") logger.debug("Asset permission nodes change signal received")
nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set']) nodes = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
system_users = instance.system_users.all().values_list('id', flat=True) system_users = instance.system_users.all()
for system_user in system_users: for system_user in system_users:
system_user.nodes.add(*tuple(nodes)) system_user.nodes.add(*tuple(nodes))
@ -59,7 +59,7 @@ def on_permission_assets_changed(sender, instance=None, action='', **kwargs):
if isinstance(instance, AssetPermission): if isinstance(instance, AssetPermission):
logger.debug("Asset permission assets change signal received") logger.debug("Asset permission assets change signal received")
assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set']) assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
system_users = instance.system_users.all().values_list('id', flat=True) system_users = instance.system_users.all()
for system_user in system_users: for system_user in system_users:
system_user.assets.add(*tuple(assets)) system_user.assets.add(*tuple(assets))

View File

@ -100,10 +100,7 @@
<form> <form>
<tr> <tr>
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Select nodes' %}" class="select2" id="node_select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select nodes' %}" class="nodes-select2" id="nodes_select2" style="width: 100%" multiple="" tabindex="4">
{% for node in nodes_remain %}
<option value="{{ node.id }}" id="opt_{{ node.id }}">{{ node.full_value }}</option>
{% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
@ -202,35 +199,22 @@ function initAssetTable() {
return table return table
} }
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
table = initAssetTable(); table = initAssetTable();
var nodeListUrl = "{% url 'api-assets:node-list' %}";
nodesSelect2Init(".nodes-select2", nodeListUrl);
$("#asset_select2").parent().find(".select2-selection").on('click', function (e) { $("#asset_select2").parent().find(".select2-selection").on('click', function (e) {
if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){ if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
$("#asset_list_modal").modal(); $("#asset_list_modal").modal();
initSelectedAssets2Table('#asset_select2');
} }
}) })
}) })
.on('click', '#btn_asset_modal_confirm', function () {
var assets = asset_table2.selected;
var options = [];
$('#asset_select2 option').each(function (i, v) {
options.push(v.value)
});
asset_table2.selected_rows.forEach(function (i) {
var name = i.hostname + '(' + i.ip + ')';
var option = new Option(name, i.id, false, true);
if (options.indexOf(i.id) === -1) {
$('#asset_select2').append(option).trigger('change');
}
});
$('#asset_select2').val(assets).trigger('change');
$("#asset_list_modal").modal('hide');
})
.on('click', '.btn-add-assets', function () { .on('click', '.btn-add-assets', function () {
var assets_selected = $("#asset_select2 option:selected").map(function () { var assets_selected = $("#asset_select2 option:selected").map(function () {
return $(this).attr('value'); return $(this).attr('value');
@ -250,7 +234,7 @@ $(document).ready(function () {
}) })
.on('click', '#btn-add-node', function () { .on('click', '#btn-add-node', function () {
var nodes_selected = {}; var nodes_selected = {};
$("#node_select2 option:selected").each(function (i, data) { $("#nodes_select2 option:selected").each(function (i, data) {
nodes_selected[$(data).attr('value')] = $(data).text(); nodes_selected[$(data).attr('value')] = $(data).text();
}); });
if (Object.keys(nodes_selected).length === 0) { if (Object.keys(nodes_selected).length === 0) {

View File

@ -111,42 +111,25 @@ var dateOptions = {
} }
}; };
var api_action = "{{ api_action }}"; var api_action = "{{ api_action }}";
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
closeOnSelect: false closeOnSelect: false
}); });
var url = "{% url 'api-assets:node-list' %}"; var url = "{% url 'api-assets:node-list' %}";
nodesSelect2Init(".nodes-select2", url); nodesSelect2Init(".nodes-select2", url);
$('#date_start').daterangepicker(dateOptions); $('#date_start').daterangepicker(dateOptions);
$('#date_expired').daterangepicker(dateOptions); $('#date_expired').daterangepicker(dateOptions);
$("#id_assets").parent().find(".select2-selection").on('click', function (e) { $("#id_assets").parent().find(".select2-selection").on('click', function (e) {
if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){ if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
$("#asset_list_modal").modal(); $("#asset_list_modal").modal();
initSelectedAssets2Table();
} }
}) })
}) })
.on('click', '#btn_asset_modal_confirm', function () {
var assets = asset_table2.selected;
var options = [];
$('#id_assets option').each(function (i, v) {
options.push(v.value)
});
asset_table2.selected_rows.forEach(function (i) {
var name = i.hostname + '(' + i.ip + ')';
var option = new Option(name, i.id, false, true);
if (options.indexOf(i.id) === -1) {
$('#id_assets').append(option).trigger('change');
}
});
$('#id_assets').val(assets).trigger('change');
$("#asset_list_modal").modal('hide');
})
.on("submit", "form", function (evt) { .on("submit", "form", function (evt) {
evt.preventDefault(); evt.preventDefault();
var the_url = '{% url 'api-perms:asset-permission-list' %}'; var the_url = '{% url 'api-perms:asset-permission-list' %}';

View File

@ -227,7 +227,6 @@ function toggle() {
$(document).ready(function(){ $(document).ready(function(){
initTable(); initTable();
initTree(); initTree();
}) })
.on('click', '.btn-del', function () { .on('click', '.btn-del', function () {
var $this = $(this); var $this = $(this);
@ -247,6 +246,7 @@ $(document).ready(function(){
}) })
.on('click', '.btn-create-permission', function () { .on('click', '.btn-create-permission', function () {
var url = "{% url 'perms:asset-permission-create' %}"; var url = "{% url 'perms:asset-permission-create' %}";
if (zTree) {
var nodes = zTree.getSelectedNodes(); var nodes = zTree.getSelectedNodes();
var _nodes = []; var _nodes = [];
var _assets = []; var _assets = [];
@ -258,6 +258,7 @@ $(document).ready(function(){
} }
}); });
url += "?assets=" + _assets.join(",") + "&nodes=" + _nodes.join(","); url += "?assets=" + _assets.join(",") + "&nodes=" + _nodes.join(",");
}
window.open(url, '_self'); window.open(url, '_self');
}).on('click', '.toggle', function (e) { }).on('click', '.toggle', function (e) {
e.preventDefault(); e.preventDefault();
@ -283,7 +284,6 @@ $(document).ready(function(){
detailRows.push(tr.attr('id')); detailRows.push(tr.attr('id'));
} }
} }
}).on('click', '#permission_list_table_filter input', function (e) { }).on('click', '#permission_list_table_filter input', function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();

View File

@ -53,11 +53,11 @@ class AssetPermissionCreateView(PermissionsMixin, CreateView):
nodes_id = nodes_id.split(",") nodes_id = nodes_id.split(",")
nodes = Node.objects.filter(id__in=nodes_id)\ nodes = Node.objects.filter(id__in=nodes_id)\
.exclude(id=Node.org_root().id) .exclude(id=Node.org_root().id)
form['nodes'].initial = nodes form.set_nodes_initial(nodes)
if assets_id: if assets_id:
assets_id = assets_id.split(",") assets_id = assets_id.split(",")
assets = Asset.objects.filter(id__in=assets_id) assets = Asset.objects.filter(id__in=assets_id)
form['assets'].initial = assets form.set_assets_initial(assets)
return form return form
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

View File

@ -17,13 +17,6 @@
padding: 10px 10px; padding: 10px 10px;
text-align: center; text-align: center;
} }
#assetTree2.ztree * {
background-color: #f8fafb;
}
#assetTree2.ztree {
background-color: #f8fafb;
}
</style> </style>
<div class="wrapper wrapper-content"> <div class="wrapper wrapper-content">

View File

@ -76,10 +76,9 @@ $(document).ready(function () {
if(!$("body").hasClass('body-small')) { if(!$("body").hasClass('body-small')) {
fix_height(); fix_height();
} }
}) });
$("[data-toggle=popover]") $("[data-toggle=popover]").popover();
.popover();
}); });

View File

@ -1,7 +1,8 @@
//jumpserver 自定义js 2015-01-29 //jumpserver 自定义js 2015-01-29
//此函数用于checkbox的全选和反选 //此函数用于checkbox的全选和反选
var checked=false; var checked = false;
function check_all(form) { function check_all(form) {
var checkboxes = document.getElementById(form); var checkboxes = document.getElementById(form);
if (checked === false) { if (checked === false) {
@ -16,26 +17,23 @@ function check_all(form) {
} }
} }
function checkAll(id, name){ function checkAll(id, name) {
var checklist = document.getElementsByName(name); var checklist = document.getElementsByName(name);
if(document.getElementById(id).checked) if (document.getElementById(id).checked) {
{ for (var i = 0; i < checklist.length; i++) {
for(var i=0;i<checklist.length;i++)
{
checklist[i].checked = 1; checklist[i].checked = 1;
} }
}else{ } else {
for(var j=0;j<checklist.length;j++) for (var j = 0; j < checklist.length; j++) {
{
checklist[j].checked = 0; checklist[j].checked = 0;
} }
} }
} }
//提取指定行的数据JSON格式 //提取指定行的数据JSON格式
function GetRowData(row){ function GetRowData(row) {
var rowData = {}; var rowData = {};
for(var j=0;j<row.cells.length; j++) { for (var j = 0; j < row.cells.length; j++) {
name = row.parentNode.rows[0].cells[j].getAttribute("Name"); name = row.parentNode.rows[0].cells[j].getAttribute("Name");
if (name) { if (name) {
var value = row.cells[j].getAttribute("Value"); var value = row.cells[j].getAttribute("Value");
@ -56,7 +54,7 @@ function GetTableDataBox() {
var checkboxes = document.getElementById("contents_form"); var checkboxes = document.getElementById("contents_form");
var id_list = []; var id_list = [];
len = checkboxes.elements.length; len = checkboxes.elements.length;
for (var i=0; i < len; i++) { for (var i = 0; i < len; i++) {
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") { if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") {
id_list.push(i); id_list.push(i);
} }
@ -65,7 +63,7 @@ function GetTableDataBox() {
tableData.push(GetRowData(tabProduct.rows[id_list[i]])); tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
} }
if (id_list.length === 0){ if (id_list.length === 0) {
alert('请至少选择一行!'); alert('请至少选择一行!');
} }
returnData.push(tableData); returnData.push(tableData);
@ -77,8 +75,8 @@ function move(from, to, from_o, to_o) {
$("#" + from + " option").each(function () { $("#" + from + " option").each(function () {
if ($(this).prop("selected") === true) { if ($(this).prop("selected") === true) {
$("#" + to).append(this); $("#" + to).append(this);
if( typeof from_o !== 'undefined'){ if (typeof from_o !== 'undefined') {
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']")); $("#" + to_o).append($("#" + from_o + " option[value='" + this.value + "']"));
} }
} }
}); });
@ -88,18 +86,18 @@ function move_left(from, to, from_o, to_o) {
$("#" + from + " option").each(function () { $("#" + from + " option").each(function () {
if ($(this).prop("selected") === true) { if ($(this).prop("selected") === true) {
$("#" + to).append(this); $("#" + to).append(this);
if( typeof from_o !== 'undefined'){ if (typeof from_o !== 'undefined') {
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']")); $("#" + to_o).append($("#" + from_o + " option[value='" + this.value + "']"));
} }
} }
$(this).attr("selected",'true'); $(this).attr("selected", 'true');
}); });
} }
function selectAll(){ function selectAll() {
// Select all check box // Select all check box
$('option').each(function(){ $('option').each(function () {
$(this).attr('selected', true); $(this).attr('selected', true);
}); });
} }
@ -131,7 +129,7 @@ function setAjaxCSRFToken() {
var sessionid = getCookie('sessionid'); var sessionid = getCookie('sessionid');
$.ajaxSetup({ $.ajaxSetup({
beforeSend: function(xhr, settings) { beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken); xhr.setRequestHeader("X-CSRFToken", csrftoken);
} }
@ -143,19 +141,16 @@ function activeNav() {
var url_array = document.location.pathname.split("/"); var url_array = document.location.pathname.split("/");
var app = url_array[1]; var app = url_array[1];
var resource = url_array[2]; var resource = url_array[2];
if (app === ''){ if (app === '') {
$('#index').addClass('active'); $('#index').addClass('active');
} } else if (app === 'xpack' && resource === 'cloud') {
else if (app === 'xpack' && resource === 'cloud') {
var item = url_array[3]; var item = url_array[3];
$("#" + app).addClass('active'); $("#" + app).addClass('active');
$('#' + app + ' #' + resource).addClass('active'); $('#' + app + ' #' + resource).addClass('active');
$('#' + app + ' #' + resource + ' #' + item + ' a').css('color', '#ffffff'); $('#' + app + ' #' + resource + ' #' + item + ' a').css('color', '#ffffff');
} } else if (app === 'settings') {
else if (app === 'settings'){
$("#" + app).addClass('active'); $("#" + app).addClass('active');
} } else {
else {
$("#" + app).addClass('active'); $("#" + app).addClass('active');
$('#' + app + ' #' + resource).addClass('active'); $('#' + app + ' #' + resource).addClass('active');
} }
@ -186,14 +181,14 @@ function formSubmit(props) {
}).done(function (data, textState, jqXHR) { }).done(function (data, textState, jqXHR) {
if (redirect_to) { if (redirect_to) {
if (props.message) { if (props.message) {
var messages="ed65330a45559c87345a0eb6ac7812d18d0d8976$[[\"__json_message\"\0540\05425\054\"asdfasdf \\u521b\\u5efa\\u6210\\u529f\"]]" var messages = "ed65330a45559c87345a0eb6ac7812d18d0d8976$[[\"__json_message\"\0540\05425\054\"asdfasdf \\u521b\\u5efa\\u6210\\u529f\"]]"
setCookie("messages", messages) setCookie("messages", messages)
} }
location.href = redirect_to; location.href = redirect_to;
} else if (typeof props.success === 'function') { } else if (typeof props.success === 'function') {
return props.success(data, textState, jqXHR); return props.success(data, textState, jqXHR);
} }
}).fail(function(jqXHR, textStatus, errorThrown) { }).fail(function (jqXHR, textStatus, errorThrown) {
if (typeof props.error === 'function') { if (typeof props.error === 'function') {
return props.error(jqXHR, textStatus, errorThrown) return props.error(jqXHR, textStatus, errorThrown)
} }
@ -233,7 +228,7 @@ function formSubmit(props) {
} }
if (fieldRef.length === 1 && formGroupRef.length === 1) { if (fieldRef.length === 1 && formGroupRef.length === 1) {
formGroupRef.addClass('has-error'); formGroupRef.addClass('has-error');
var help_msg = v.join("<br/>") ; var help_msg = v.join("<br/>");
helpBlockRef.html(help_msg); helpBlockRef.html(help_msg);
} else { } else {
$.each(v, function (kk, vv) { $.each(v, function (kk, vv) {
@ -241,7 +236,7 @@ function formSubmit(props) {
$.each(vv, function (kkk, vvv) { $.each(vv, function (kkk, vvv) {
noneFieldErrorMsg += " " + vvv + '<br/>'; noneFieldErrorMsg += " " + vvv + '<br/>';
}) })
} else{ } else {
noneFieldErrorMsg += vv + '<br/>'; noneFieldErrorMsg += vv + '<br/>';
} }
}) })
@ -264,7 +259,7 @@ function requestApi(props) {
var user_fail_message = props.fail_message; var user_fail_message = props.fail_message;
var default_failed_message = gettext('An unknown error occurred while updating..'); var default_failed_message = gettext('An unknown error occurred while updating..');
var flash_message = props.flash_message || true; var flash_message = props.flash_message || true;
if (props.flash_message === false){ if (props.flash_message === false) {
flash_message = false; flash_message = false;
} }
@ -274,7 +269,7 @@ function requestApi(props) {
data: props.body, data: props.body,
contentType: props.content_type || "application/json; charset=utf-8", contentType: props.content_type || "application/json; charset=utf-8",
dataType: props.data_type || "json" dataType: props.data_type || "json"
}).done(function(data, textStatue, jqXHR) { }).done(function (data, textStatue, jqXHR) {
if (flash_message) { if (flash_message) {
var msg = ""; var msg = "";
if (user_success_message) { if (user_success_message) {
@ -287,7 +282,7 @@ function requestApi(props) {
if (typeof props.success === 'function') { if (typeof props.success === 'function') {
return props.success(data); return props.success(data);
} }
}).fail(function(jqXHR, textStatus, errorThrown) { }).fail(function (jqXHR, textStatus, errorThrown) {
if (flash_message) { if (flash_message) {
var msg = ""; var msg = "";
if (user_fail_message) { if (user_fail_message) {
@ -315,17 +310,17 @@ function requestApi(props) {
function objectDelete(obj, name, url, redirectTo) { function objectDelete(obj, name, url, redirectTo) {
function doDelete() { function doDelete() {
var body = {}; var body = {};
var success = function() { var success = function () {
// swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success"); // swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
if (!redirectTo) { if (!redirectTo) {
$(obj).parent().parent().remove(); $(obj).parent().parent().remove();
} else { } else {
window.location.href=redirectTo; window.location.href = redirectTo;
} }
}; };
var fail = function() { var fail = function () {
// swal("错误", "删除"+"[ "+name+" ]"+"遇到错误", "error"); // swal("错误", "删除"+"[ "+name+" ]"+"遇到错误", "error");
swal(gettext('Error'), "[ "+name+" ]" + gettext("Being used by the asset, please unbind the asset first."), "error"); swal(gettext('Error'), "[ " + name + " ]" + gettext("Being used by the asset, please unbind the asset first."), "error");
}; };
requestApi({ requestApi({
url: url, url: url,
@ -336,6 +331,7 @@ function objectDelete(obj, name, url, redirectTo) {
error: fail error: fail
}); });
} }
swal({ swal({
title: gettext('Are you sure about deleting it?'), title: gettext('Are you sure about deleting it?'),
text: " [" + name + "] ", text: " [" + name + "] ",
@ -350,22 +346,21 @@ function objectDelete(obj, name, url, redirectTo) {
}); });
} }
function orgDelete(obj, name, url, redirectTo){ function orgDelete(obj, name, url, redirectTo) {
function doDelete() { function doDelete() {
var body = {}; var body = {};
var success = function() { var success = function () {
if (!redirectTo) { if (!redirectTo) {
$(obj).parent().parent().remove(); $(obj).parent().parent().remove();
} else { } else {
window.location.href=redirectTo; window.location.href = redirectTo;
} }
}; };
var fail = function(responseText, status) { var fail = function (responseText, status) {
if (status === 400){ if (status === 400) {
swal(gettext("Error"), "[ " + name + " ] " + gettext("The organization contains undeleted information. Please try again after deleting"), "error"); swal(gettext("Error"), "[ " + name + " ] " + gettext("The organization contains undeleted information. Please try again after deleting"), "error");
} } else if (status === 405) {
else if (status === 405){ swal(gettext("Error"), " [ " + name + " ] " + gettext("Do not perform this operation under this organization. Try again after switching to another organization"), "error");
swal(gettext("Error"), " [ "+ name + " ] " + gettext("Do not perform this operation under this organization. Try again after switching to another organization"), "error");
} }
}; };
requestApi({ requestApi({
@ -377,6 +372,7 @@ function orgDelete(obj, name, url, redirectTo){
error: fail error: fail
}); });
} }
swal({ swal({
title: gettext("Please ensure that the following information in the organization has been deleted"), title: gettext("Please ensure that the following information in the organization has been deleted"),
text: gettext("User list、User group、Asset list、Domain list、Admin user、System user、Labels、Asset permission"), text: gettext("User list、User group、Asset list、Domain list、Admin user、System user、Labels、Asset permission"),
@ -391,11 +387,10 @@ function orgDelete(obj, name, url, redirectTo){
}); });
} }
$.fn.serializeObject = function() $.fn.serializeObject = function () {
{
var o = {}; var o = {};
var a = this.serializeArray(); var a = this.serializeArray();
$.each(a, function() { $.each(a, function () {
if (o[this.name] !== undefined) { if (o[this.name] !== undefined) {
if (!o[this.name].push) { if (!o[this.name].push) {
o[this.name] = [o[this.name]]; o[this.name] = [o[this.name]];
@ -413,12 +408,11 @@ function makeLabel(data) {
} }
var jumpserver = {}; var jumpserver = {};
jumpserver.checked = false; jumpserver.checked = false;
jumpserver.selected = {}; jumpserver.selected = {};
jumpserver.language = { jumpserver.language = {
processing: gettext('Loading ...'), processing: gettext('Loading') + '...',
search: gettext('Search'), search: gettext('Search'),
select: { select: {
rows: { rows: {
@ -462,7 +456,11 @@ jumpserver.initDataTable = function (options) {
$(td).html('<input type="checkbox" class="text-center ipt_check" id=99991937>'.replace('99991937', cellData)); $(td).html('<input type="checkbox" class="text-center ipt_check" id=99991937>'.replace('99991937', cellData));
} }
}, },
{className: 'text-center', render: $.fn.dataTable.render.text(), targets: '_all'} {
className: 'text-center',
render: $.fn.dataTable.render.text(),
targets: '_all'
}
]; ];
columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs; columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs;
var select = { var select = {
@ -486,15 +484,15 @@ jumpserver.initDataTable = function (options) {
language: jumpserver.language, language: jumpserver.language,
lengthMenu: [[10, 15, 25, 50, -1], [10, 15, 25, 50, "All"]] lengthMenu: [[10, 15, 25, 50, -1], [10, 15, 25, 50, "All"]]
}); });
table.on('select', function(e, dt, type, indexes) { table.on('select', function (e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$(); var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', true); $node.find('input.ipt_check').prop('checked', true);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true
}).on('deselect', function(e, dt, type, indexes) { }).on('deselect', function (e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$(); var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', false); $node.find('input.ipt_check').prop('checked', false);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false
}).on('draw', function(){ }).on('draw', function () {
$('#op').html(options.op_html || ''); $('#op').html(options.op_html || '');
$('#uc').html(options.uc_html || ''); $('#uc').html(options.uc_html || '');
$('[data-toggle="popover"]').popover({ $('[data-toggle="popover"]').popover({
@ -506,15 +504,15 @@ jumpserver.initDataTable = function (options) {
$('[data-toggle="popover"]').not(this).popover('hide'); $('[data-toggle="popover"]').not(this).popover('hide');
}); });
}); });
$('.ipt_check_all').on('click', function() { $('.ipt_check_all').on('click', function () {
if ($(this).prop("checked")) { if ($(this).prop("checked")) {
$(this).closest('table').find('.ipt_check').prop('checked', true); $(this).closest('table').find('.ipt_check').prop('checked', true);
jumpserver.checked = true; jumpserver.checked = true;
table.rows({search:'applied', page:'current'}).select(); table.rows({search: 'applied', page: 'current'}).select();
} else { } else {
$(this).closest('table').find('.ipt_check').prop('checked', false); $(this).closest('table').find('.ipt_check').prop('checked', false);
jumpserver.checked = false; jumpserver.checked = false;
table.rows({search:'applied', page:'current'}).deselect(); table.rows({search: 'applied', page: 'current'}).deselect();
} }
}); });
@ -535,6 +533,7 @@ jumpserver.initServerSideDataTable = function (options) {
// options = { // options = {
// ele *: $('#dataTable_id'), // ele *: $('#dataTable_id'),
// ajax_url *: '{% url 'users:user-list-api' %}', // ajax_url *: '{% url 'users:user-list-api' %}',
// select_style: 'multi',
// columns *: [{data: ''}, ....], // columns *: [{data: ''}, ....],
// dom: 'fltip', // dom: 'fltip',
// i18n_url: '{% static "js/...../en-us.json" %}', // i18n_url: '{% static "js/...../en-us.json" %}',
@ -560,9 +559,10 @@ jumpserver.initServerSideDataTable = function (options) {
render: $.fn.dataTable.render.text() render: $.fn.dataTable.render.text()
} }
]; ];
var select_style = options.select_style || 'multi';
columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs; columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs;
var select = { var select = {
style: 'multi', style: select_style,
selector: 'td:first-child' selector: 'td:first-child'
}; };
var table = ele.DataTable({ var table = ele.DataTable({
@ -576,8 +576,8 @@ jumpserver.initServerSideDataTable = function (options) {
processing: true, processing: true,
searchDelay: 800, searchDelay: 800,
ajax: { ajax: {
url: options.ajax_url , url: options.ajax_url,
error: function(jqXHR, textStatus, errorThrown) { error: function (jqXHR, textStatus, errorThrown) {
var msg = gettext("Unknown error occur"); var msg = gettext("Unknown error occur");
if (jqXHR.responseJSON) { if (jqXHR.responseJSON) {
if (jqXHR.responseJSON.error) { if (jqXHR.responseJSON.error) {
@ -590,7 +590,7 @@ jumpserver.initServerSideDataTable = function (options) {
}, },
data: function (data) { data: function (data) {
delete data.columns; delete data.columns;
if (data.length !== null){ if (data.length !== null) {
data.limit = data.length; data.limit = data.length;
delete data.length; delete data.length;
} }
@ -629,8 +629,8 @@ jumpserver.initServerSideDataTable = function (options) {
data.order = order; data.order = order;
} }
}, },
dataFilter: function(data){ dataFilter: function (data) {
var json = jQuery.parseJSON( data ); var json = jQuery.parseJSON(data);
json.recordsTotal = json.count; json.recordsTotal = json.count;
json.recordsFiltered = json.count; json.recordsFiltered = json.count;
return JSON.stringify(json); // return JSON string return JSON.stringify(json); // return JSON string
@ -644,35 +644,36 @@ jumpserver.initServerSideDataTable = function (options) {
}); });
table.selected = []; table.selected = [];
table.selected_rows = []; table.selected_rows = [];
table.on('select', function(e, dt, type, indexes) { table.on('select', function (e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$(); var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', true); $node.find('input.ipt_check').prop('checked', true);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true; jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true;
if (type === 'row') { if (type === 'row') {
var rows = table.rows(indexes).data(); var rows = table.rows(indexes).data();
$.each(rows, function (id, row) { $.each(rows, function (id, row) {
if (row.id && $.inArray(row.id, table.selected) === -1) {
table.selected.push(row.id);
table.selected_rows.push(row); table.selected_rows.push(row);
if (row.id && $.inArray(row.id, table.selected) === -1){
table.selected.push(row.id)
} }
}) })
} }
}).on('deselect', function(e, dt, type, indexes) { }).on('deselect', function (e, dt, type, indexes) {
var $node = table[ type ]( indexes ).nodes().to$(); var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', false); $node.find('input.ipt_check').prop('checked', false);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false; jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false;
if (type === 'row') { if (type === 'row') {
var rows = table.rows(indexes).data(); var rows = table.rows(indexes).data();
$.each(rows, function (id, row) { $.each(rows, function (id, row) {
if (row.id){ if (row.id) {
var index = table.selected.indexOf(row.id); var index = table.selected.indexOf(row.id);
if (index > -1){ if (index > -1) {
table.selected.splice(index, 1) table.selected.splice(index, 1);
table.selected_rows.splice(index, 1);
} }
} }
}) })
} }
}).on('draw', function(){ }).on('draw', function () {
$('[data-toggle="popover"]').popover({ $('[data-toggle="popover"]').popover({
html: true, html: true,
placement: 'bottom', placement: 'bottom',
@ -690,7 +691,7 @@ jumpserver.initServerSideDataTable = function (options) {
$.each(table.selected, function (id, data) { $.each(table.selected, function (id, data) {
var index = table_data.indexOf(data); var index = table_data.indexOf(data);
if (index > -1){ if (index > -1) {
table.rows(index).select() table.rows(index).select()
} }
}); });
@ -701,13 +702,16 @@ jumpserver.initServerSideDataTable = function (options) {
$('#fa').html(options.fa_html || ''); $('#fa').html(options.fa_html || '');
}); });
var table_id = table.settings()[0].sTableId; var table_id = table.settings()[0].sTableId;
$('#' + table_id + ' .ipt_check_all').on('click', function() { $('#' + table_id + ' .ipt_check_all').on('click', function () {
if (select_style !== 'multi') {
return
}
if ($(this).prop("checked")) { if ($(this).prop("checked")) {
$(this).closest('table').find('.ipt_check').prop('checked', true); $(this).closest('table').find('.ipt_check').prop('checked', true);
table.rows({search:'applied', page:'current'}).select(); table.rows({search: 'applied', page: 'current'}).select();
} else { } else {
$(this).closest('table').find('.ipt_check').prop('checked', false); $(this).closest('table').find('.ipt_check').prop('checked', false);
table.rows({search:'applied', page:'current'}).deselect(); table.rows({search: 'applied', page: 'current'}).deselect();
} }
}); });
@ -728,7 +732,7 @@ String.prototype.replaceAll = function (exp, newStr) {
* 原型字符串格式化 * 原型字符串格式化
* @param args 格式化参数值 * @param args 格式化参数值
*/ */
String.prototype.format = function(args) { String.prototype.format = function (args) {
var result = this; var result = this;
if (arguments.length < 1) { if (arguments.length < 1) {
return result; return result;
@ -738,7 +742,7 @@ String.prototype.format = function(args) {
if (arguments.length == 1 && typeof (args) == "object") { if (arguments.length == 1 && typeof (args) == "object") {
data = args; data = args;
} }
for ( var key in data) { for (var key in data) {
var value = data[key]; var value = data[key];
if (undefined != value) { if (undefined != value) {
result = result.replaceAll("\\{" + key + "\\}", value); result = result.replaceAll("\\{" + key + "\\}", value);
@ -767,26 +771,26 @@ function delCookie(key) {
} }
function createPopover(dataset, title, callback) { function createPopover(dataset, title, callback) {
if (callback !== undefined){ if (callback !== undefined) {
var new_dataset = []; var new_dataset = [];
$.each(dataset, function (index, value) { $.each(dataset, function (index, value) {
new_dataset.push(callback(value)) new_dataset.push(callback(value))
}); });
dataset = new_dataset; dataset = new_dataset;
} }
var data_content = dataset.join("</br>"); var data_content = dataset.join("<br>");
var html = "<a data-toggle='popover' data-content='" + data_content + "'>" + dataset.length + "</a>"; var html = "<a data-toggle='popover' data-content='" + data_content + "'>" + dataset.length + "</a>";
return html; return html;
} }
$(function () { $(function () {
(function ($) { (function ($) {
$.getUrlParam = function (name) { $.getUrlParam = function (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg); var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null; if (r != null) return unescape(r[2]);
return null;
} }
})(jQuery); })(jQuery);
}); });
@ -794,12 +798,13 @@ function createPopover(dataset, title, callback) {
function getUrlParam(name) { function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg); var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null; if (r != null) return unescape(r[2]);
return null;
} }
function setUrlParam(url, name, value) { function setUrlParam(url, name, value) {
var urlArray = url.split("?"); var urlArray = url.split("?");
if (urlArray.length===1){ if (urlArray.length === 1) {
url += "?" + name + "=" + value; url += "?" + name + "=" + value;
} else { } else {
var oriParam = urlArray[1].split("&"); var oriParam = urlArray[1].split("&");
@ -836,12 +841,11 @@ var rules_id_map_label = {
'id_security_password_special_char': gettext('Must contain special characters') 'id_security_password_special_char': gettext('Must contain special characters')
}; };
function getRuleLabel(rule){ function getRuleLabel(rule) {
var label = ''; var label = '';
if (rule.key === rules_short_map_id['min']){ if (rule.key === rules_short_map_id['min']) {
label = rules_id_map_label[rule.key].replace('{N}', rule.value) label = rules_id_map_label[rule.key].replace('{N}', rule.value)
} } else {
else{
label = rules_id_map_label[rule.key] label = rules_id_map_label[rule.key]
} }
return label return label
@ -850,38 +854,33 @@ function getRuleLabel(rule){
// 校验密码-改变规则颜色 // 校验密码-改变规则颜色
function checkPasswordRules(password, minLength) { function checkPasswordRules(password, minLength) {
if (wordMinLength(password, minLength)) { if (wordMinLength(password, minLength)) {
$('#'+rules_short_map_id['min']).css('color', 'green') $('#' + rules_short_map_id['min']).css('color', 'green')
} } else {
else { $('#' + rules_short_map_id['min']).css('color', '#908a8a')
$('#'+rules_short_map_id['min']).css('color', '#908a8a')
} }
if (wordUpperCase(password)) { if (wordUpperCase(password)) {
$('#'+rules_short_map_id['upper']).css('color', 'green') $('#' + rules_short_map_id['upper']).css('color', 'green')
} } else {
else { $('#' + rules_short_map_id['upper']).css('color', '#908a8a')
$('#'+rules_short_map_id['upper']).css('color', '#908a8a')
} }
if (wordLowerCase(password)) { if (wordLowerCase(password)) {
$('#'+rules_short_map_id['lower']).css('color', 'green') $('#' + rules_short_map_id['lower']).css('color', 'green')
} } else {
else { $('#' + rules_short_map_id['lower']).css('color', '#908a8a')
$('#'+rules_short_map_id['lower']).css('color', '#908a8a')
} }
if (wordNumber(password)) { if (wordNumber(password)) {
$('#'+rules_short_map_id['number']).css('color', 'green') $('#' + rules_short_map_id['number']).css('color', 'green')
} } else {
else { $('#' + rules_short_map_id['number']).css('color', '#908a8a')
$('#'+rules_short_map_id['number']).css('color', '#908a8a')
} }
if (wordSpecialChar(password)) { if (wordSpecialChar(password)) {
$('#'+rules_short_map_id['special']).css('color', 'green') $('#' + rules_short_map_id['special']).css('color', 'green')
} } else {
else { $('#' + rules_short_map_id['special']).css('color', '#908a8a')
$('#'+rules_short_map_id['special']).css('color', '#908a8a')
} }
} }
@ -891,18 +890,22 @@ function wordMinLength(word, minLength) {
var re = new RegExp("^(.{" + minLength + ",})$"); var re = new RegExp("^(.{" + minLength + ",})$");
return word.match(re) return word.match(re)
} }
// 大写字母 // 大写字母
function wordUpperCase(word) { function wordUpperCase(word) {
return word.match(/([A-Z]+)/) return word.match(/([A-Z]+)/)
} }
// 小写字母 // 小写字母
function wordLowerCase(word) { function wordLowerCase(word) {
return word.match(/([a-z]+)/) return word.match(/([a-z]+)/)
} }
// 数字字符 // 数字字符
function wordNumber(word) { function wordNumber(word) {
return word.match(/([\d]+)/) return word.match(/([\d]+)/)
} }
// 特殊字符 // 特殊字符
function wordSpecialChar(word) { function wordSpecialChar(word) {
return word.match(/[`,~,!,@,#,\$,%,\^,&,\*,\(,\),\-,_,=,\+,\{,\},\[,\],\|,\\,;,',:,",\,,\.,<,>,\/,\?]+/) return word.match(/[`,~,!,@,#,\$,%,\^,&,\*,\(,\),\-,_,=,\+,\{,\},\[,\],\|,\\,;,',:,",\,,\.,<,>,\/,\?]+/)
@ -920,7 +923,7 @@ function popoverPasswordRules(password_check_rules, $el) {
} }
// 初始化弹窗popover // 初始化弹窗popover
function initPopover($container, $progress, $idPassword, $el, password_check_rules, i18n_fallback){ function initPopover($container, $progress, $idPassword, $el, password_check_rules, i18n_fallback) {
options = {}; options = {};
// User Interface // User Interface
options.ui = { options.ui = {
@ -944,37 +947,6 @@ function initPopover($container, $progress, $idPassword, $el, password_check_rul
popoverPasswordRules(password_check_rules, $el); popoverPasswordRules(password_check_rules, $el);
} }
// 解决input框中的资产和弹出表格中资产的显示不一致
function initSelectedAssets2Table(id){
if (!id) {
id = "#id_assets"
}
var inputAssets = $(id).val();
var selectedAssets = asset_table2.selected.concat();
// input assets无table assets选中则取消勾选(再次click)
if (selectedAssets.length !== 0){
$.each(selectedAssets, function (index, assetId){
if ($.inArray(assetId, inputAssets) === -1){
$('#'+assetId).trigger('click'); // 取消勾选
}
});
}
// input assets有table assets没选则选中(click)
if (inputAssets !== null){
asset_table2.selected = inputAssets;
$.each(inputAssets, function(index, assetId){
var dom = document.getElementById(assetId);
if (dom !== null){
var selected = dom.parentElement.parentElement.className.indexOf('selected')
}
if (selected === -1){
$('#'+assetId).trigger('click');
}
});
}
}
function rootNodeAddDom(ztree, callback) { function rootNodeAddDom(ztree, callback) {
@ -1002,7 +974,7 @@ function APIExportData(props) {
var params = props.params || {}; var params = props.params || {};
params['format'] = props.format; params['format'] = props.format;
params['spm'] = data.spm; params['spm'] = data.spm;
for (var k in params){ for (var k in params) {
export_url = setUrlParam(export_url, k, params[k]) export_url = setUrlParam(export_url, k, params[k])
} }
window.open(export_url); window.open(export_url);
@ -1013,7 +985,7 @@ function APIExportData(props) {
}) })
} }
function APIImportData(props){ function APIImportData(props) {
props = props || {}; props = props || {};
$.ajax({ $.ajax({
url: props.url, url: props.url,
@ -1022,12 +994,12 @@ function APIImportData(props){
data: props.body, data: props.body,
contentType: props.content_type || 'text/csv', contentType: props.content_type || 'text/csv',
success: function (data) { success: function (data) {
if(props.method === 'POST'){ if (props.method === 'POST') {
$('#created_failed').html(''); $('#created_failed').html('');
$('#created_failed_detail').html(''); $('#created_failed_detail').html('');
$('#success_created').html(gettext("Import Success")); $('#success_created').html(gettext("Import Success"));
$('#success_created_detail').html("Count" + ": " + data.length); $('#success_created_detail').html("Count" + ": " + data.length);
}else{ } else {
$('#updated_failed').html(''); $('#updated_failed').html('');
$('#updated_failed_detail').html(''); $('#updated_failed_detail').html('');
$('#success_updated').html(gettext("Update Success")); $('#success_updated').html(gettext("Update Success"));
@ -1038,11 +1010,11 @@ function APIImportData(props){
}, },
error: function (error) { error: function (error) {
var data = error.responseJSON; var data = error.responseJSON;
if (data instanceof Array){ if (data instanceof Array) {
var html = ''; var html = '';
var li = ''; var li = '';
var err = ''; var err = '';
$.each(data, function (index, item){ $.each(data, function (index, item) {
err = ''; err = '';
for (var prop in item) { for (var prop in item) {
err += prop + ": " + item[prop][0] + " " err += prop + ": " + item[prop][0] + " "
@ -1053,16 +1025,15 @@ function APIImportData(props){
} }
}); });
html = "<ul>" + html + "</ul>" html = "<ul>" + html + "</ul>"
} } else {
else {
html = error.responseText html = error.responseText
} }
if(props.method === 'POST'){ if (props.method === 'POST') {
$('#success_created').html(''); $('#success_created').html('');
$('#success_created_detail').html(''); $('#success_created_detail').html('');
$('#created_failed').html(gettext("Import failed")); $('#created_failed').html(gettext("Import failed"));
$('#created_failed_detail').html(html); $('#created_failed_detail').html(html);
}else{ } else {
$('#success_updated').html(''); $('#success_updated').html('');
$('#success_updated_detail').html(''); $('#success_updated_detail').html('');
$('#updated_failed').html(gettext("Update failed")); $('#updated_failed').html(gettext("Update failed"));
@ -1073,7 +1044,7 @@ function APIImportData(props){
} }
function htmlEscape ( d ) { function htmlEscape(d) {
return typeof d === 'string' ? return typeof d === 'string' ?
d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') : d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
d; d;
@ -1081,10 +1052,9 @@ function htmlEscape ( d ) {
function objectAttrsIsList(obj, attrs) { function objectAttrsIsList(obj, attrs) {
attrs.forEach(function (attr) { attrs.forEach(function (attr) {
if (!obj[attr]){ if (!obj[attr]) {
obj[attr] = [] obj[attr] = []
} } else if (obj[attr] && !(obj[attr] instanceof Array)) {
else if (obj[attr] && !(obj[attr] instanceof Array)){
obj[attr] = [obj[attr]] obj[attr] = [obj[attr]]
} }
}) })
@ -1107,8 +1077,8 @@ function objectAttrsIsBool(obj, attrs) {
} }
function cleanDateStr(d) { function cleanDateStr(d) {
for (var i=0;i<3;i++) { for (var i = 0; i < 3; i++) {
if (!isNaN(Date.parse(d))){ if (!isNaN(Date.parse(d))) {
return d; return d;
} }
if (!isNaN(Number(d))) { if (!isNaN(Number(d))) {
@ -1145,7 +1115,7 @@ function toSafeLocalDateStr(d) {
function getUrlParams(url) { function getUrlParams(url) {
url = url.split("?"); url = url.split("?");
var params = ""; var params = "";
if (url.length === 2){ if (url.length === 2) {
params = url[1]; params = url[1];
} }
return params return params
@ -1167,7 +1137,7 @@ function getTimeUnits(u) {
function timeOffset(a, b) { function timeOffset(a, b) {
var start = safeDate(a); var start = safeDate(a);
var end = safeDate(b); var end = safeDate(b);
var offset = (end - start)/1000; var offset = (end - start) / 1000;
var days = offset / 3600 / 24; var days = offset / 3600 / 24;
var hours = offset / 3600; var hours = offset / 3600;
@ -1192,7 +1162,7 @@ function readFile(ref) {
if (hasFile) { if (hasFile) {
var reader = new FileReader();//新建一个FileReader var reader = new FileReader();//新建一个FileReader
reader.readAsText(files[0], "UTF-8");//读取文件 reader.readAsText(files[0], "UTF-8");//读取文件
reader.onload = function(evt){ //读取完文件之后会回来这里 reader.onload = function (evt) { //读取完文件之后会回来这里
ref.trigger("onload", evt.target.result); ref.trigger("onload", evt.target.result);
}; };
} else { } else {
@ -1211,7 +1181,7 @@ function nodesSelect2Init(selector, url) {
var page = params.page || 1; var page = params.page || 1;
var query = { var query = {
search: params.term, search: params.term,
offset: (page -1) * 10, offset: (page - 1) * 10,
limit: 10 limit: 10
}; };
return query return query
@ -1221,7 +1191,7 @@ function nodesSelect2Init(selector, url) {
return {id: v.id, text: v.full_value} return {id: v.id, text: v.full_value}
}); });
var more = !!data.next; var more = !!data.next;
return {results: results, pagination: {"more": more }} return {results: results, pagination: {"more": more}}
} }
}, },
}) })