jumpserver/apps/static/js/jumpserver.js

1591 lines
49 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//jumpserver 自定义js 2015-01-29
//此函数用于checkbox的全选和反选
var checked = false;
function check_all(form) {
var checkboxes = document.getElementById(form);
if (checked === false) {
checked = true;
} else {
checked = false;
}
for (var i = 0; i < checkboxes.elements.length; i++) {
if (checkboxes.elements[i].type == "checkbox") {
checkboxes.elements[i].checked = checked;
}
}
}
function checkAll(id, name) {
var checklist = document.getElementsByName(name);
if (document.getElementById(id).checked) {
for (var i = 0; i < checklist.length; i++) {
checklist[i].checked = 1;
}
} else {
for (var j = 0; j < checklist.length; j++) {
checklist[j].checked = 0;
}
}
}
//提取指定行的数据JSON格式
function GetRowData(row) {
var rowData = {};
for (var j = 0; j < row.cells.length; j++) {
name = row.parentNode.rows[0].cells[j].getAttribute("Name");
if (name) {
var value = row.cells[j].getAttribute("Value");
if (!value) {
value = row.cells[j].innerHTML;
}
rowData[name] = value;
}
}
return rowData;
}
//此函数用于在多选提交时至少要选择一行
function GetTableDataBox() {
var tabProduct = document.getElementById("editable");
var tableData = [];
var returnData = [];
var checkboxes = document.getElementById("contents_form");
var id_list = [];
len = checkboxes.elements.length;
for (var i = 0; i < len; i++) {
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") {
id_list.push(i);
}
}
for (i in id_list) {
tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
}
if (id_list.length === 0) {
alert('请至少选择一行!');
}
returnData.push(tableData);
returnData.push(id_list.length);
return returnData;
}
function move(from, to, from_o, to_o) {
$("#" + from + " option").each(function () {
if ($(this).prop("selected") === true) {
$("#" + to).append(this);
if (typeof from_o !== 'undefined') {
$("#" + to_o).append($("#" + from_o + " option[value='" + this.value + "']"));
}
}
});
}
function move_left(from, to, from_o, to_o) {
$("#" + from + " option").each(function () {
if ($(this).prop("selected") === true) {
$("#" + to).append(this);
if (typeof from_o !== 'undefined') {
$("#" + to_o).append($("#" + from_o + " option[value='" + this.value + "']"));
}
}
$(this).attr("selected", 'true');
});
}
function selectAll() {
// Select all check box
$('option').each(function () {
$(this).attr('selected', true);
});
}
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
// break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function setAjaxCSRFToken() {
let prefix = getCookie('SESSION_COOKIE_NAME_PREFIX');
if (!prefix || [`""`, `''`].indexOf(prefix) > -1) { prefix = ''; }
var csrftoken = getCookie(`${prefix}csrftoken`);
var sessionid = getCookie(`${prefix}sessionid`);
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
}
function activeNav(prefix) {
if (!prefix) {
prefix = '/core'
}
var path = document.location.pathname;
path = path.replace(prefix, '');
var urlArray = path.split("/");
var app = urlArray[1];
var resource = urlArray[2];
if (app === '') {
$('#index').addClass('active');
} else if (app === 'xpack' && resource === 'cloud') {
var item = urlArray[3];
$("#" + app).addClass('active');
$('#' + app + ' #' + resource).addClass('active');
$('#' + app + ' #' + resource + ' #' + item + ' a').css('color', '#ffffff');
} else if (app === 'settings') {
$("#" + app).addClass('active');
} else {
$("#" + app).addClass('active');
$('#' + app + ' #' + resource).addClass('active');
$('#' + app + ' #' + resource.replace(/-/g, '_')).addClass('active');
}
}
function formSubmit(props) {
/*
{
"form": $("form"),
"data": {},
"url": "",
"method": "POST",
"redirect_to": "",
"success": function(data, textStatue, jqXHR){},
"error": function(jqXHR, textStatus, errorThrown) {},
"message": "",
}
*/
props = props || {};
var data = props.data || props.form.serializeObject();
var redirectTo = props.redirect_to || props.redirectTo;
$.ajax({
url: props.url,
type: props.method || 'POST',
data: JSON.stringify(data),
contentType: props.content_type || "application/json; charset=utf-8",
dataType: props.data_type || "json"
}).done(function (data, textState, jqXHR) {
if (redirectTo) {
location.href = redirectTo;
} else if (typeof props.success === 'function') {
return props.success(data, textState, jqXHR);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
if (typeof props.error === 'function') {
return props.error(jqXHR, textStatus, errorThrown)
}
if (!props.form) {
alert(jqXHR.responseText);
return
}
if (jqXHR.status === 400) {
var errors = jqXHR.responseJSON;
var noneFieldErrorRef = props.form.children('.alert-danger');
if (noneFieldErrorRef.length !== 1) {
props.form.prepend('<div class="alert alert-danger has-error" style="display: none"></div>');
noneFieldErrorRef = props.form.children('.alert-danger');
}
var noneFieldErrorMsg = "";
noneFieldErrorRef.css("display", "none");
noneFieldErrorRef.html("");
props.form.find(".help-block.error").html("");
props.form.find(".form-group.has-error").removeClass("has-error");
if (typeof errors !== "object") {
noneFieldErrorMsg = errors;
if (noneFieldErrorRef.length === 1) {
noneFieldErrorRef.css('display', 'block');
noneFieldErrorRef.html(noneFieldErrorMsg);
}
return
}
$.each(errors, function (k, v) {
var fieldRef = props.form.find('[name="' + k + '"]');
var formGroupRef = fieldRef.parents('.form-group');
var parentRef = fieldRef.parent();
var helpBlockRef = parentRef.children('.help-block.error');
if (helpBlockRef.length === 0) {
parentRef.append('<div class="help-block error"></div>');
helpBlockRef = parentRef.children('.help-block.error');
}
if (fieldRef.length === 1 && formGroupRef.length === 1) {
formGroupRef.addClass('has-error');
var help_msg = v.join("<br/>");
helpBlockRef.html(help_msg);
} else {
$.each(v, function (kk, vv) {
if (typeof vv === "object") {
$.each(vv, function (kkk, vvv) {
noneFieldErrorMsg += " " + vvv + '<br/>';
})
} else {
noneFieldErrorMsg += vv + '<br/>';
}
})
}
});
if (noneFieldErrorRef.length === 1 && noneFieldErrorMsg !== '') {
noneFieldErrorRef.css('display', 'block');
noneFieldErrorRef.html(noneFieldErrorMsg);
}
$('.has-error :visible').get(0).scrollIntoView();
}
})
}
function requestApi(props) {
// props = {url: .., body: , success: , error: , method: ,}
props = props || {};
var user_success_message = props.success_message;
var default_success_message = gettext('Update is successful!');
var user_fail_message = props.fail_message;
var default_failed_message = gettext('An unknown error occurred while updating..');
var flash_message = props.flash_message || true;
if (props.flash_message === false) {
flash_message = false;
}
var dataBody = props.body || props.data;
if (typeof(dataBody) === "object") {
dataBody = JSON.stringify(dataBody)
}
$.ajax({
url: props.url,
type: props.method || "PATCH",
data: dataBody,
contentType: props.content_type || "application/json; charset=utf-8",
dataType: props.data_type || "json"
}).done(function (data, textStatue, jqXHR) {
if (flash_message) {
var msg = "";
if (user_success_message) {
msg = user_success_message;
} else {
msg = default_success_message;
}
toastr.success(msg);
}
if (typeof props.success === 'function') {
return props.success(data);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
if (flash_message) {
var msg = "";
if (user_fail_message) {
msg = user_fail_message;
} else if (jqXHR.responseJSON) {
if (jqXHR.responseJSON.error) {
msg = jqXHR.responseJSON.error
} else if (jqXHR.responseJSON.msg) {
msg = jqXHR.responseJSON.msg
} else if (jqXHR.responseJSON.detail) {
msg = jqXHR.responseJSON.detail
}
}
if (msg === "") {
msg = default_failed_message;
}
toastr.error(msg);
}
if (typeof props.error === 'function') {
return props.error(jqXHR.responseText, jqXHR.responseJSON, jqXHR.status);
}
});
// return true;
}
// Sweet Alert for Delete
function objectDelete(obj, name, url, redirectTo, title, success_message) {
function doDelete() {
var body = {};
var success = function () {
if (!redirectTo) {
$(obj).parent().parent().remove();
} else {
window.location.href = redirectTo;
}
};
var fail = function (responseText, responseJSON, status) {
var errorMsg = '';
if (responseJSON && responseJSON.error) {
errorMsg = '';
} else if (status === 404) {
errorMsg = gettext("Not found")
} else {
errorMsg = gettext("Server error")
}
swal(gettext('Error'), "[ " + name + " ] " + errorMsg);
};
requestApi({
url: url,
body: JSON.stringify(body),
method: 'DELETE',
success_message: success_message || gettext("Delete the success"),
success: success,
error: fail
});
}
swal({
title: title || gettext('Are you sure about deleting it?'),
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: gettext('Cancel'),
confirmButtonColor: "#ed5565",
confirmButtonText: gettext('Confirm'),
closeOnConfirm: true,
}, function () {
doDelete()
});
}
function orgDelete(obj, name, url, redirectTo) {
function doDelete() {
var body = {};
var success = function () {
if (!redirectTo) {
$(obj).parent().parent().remove();
} else {
window.location.href = redirectTo;
}
};
var fail = function (responseText, status) {
if (status === 400) {
swal(gettext("Error"), "[ " + name + " ] " + gettext("The organization contains undeleted information. Please try again after deleting"), "error");
} 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");
}
};
requestApi({
url: url,
body: JSON.stringify(body),
method: 'DELETE',
success_message: gettext("Delete the success"),
success: success,
error: fail
});
}
swal({
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"),
type: "warning",
showCancelButton: true,
cancelButtonText: gettext('Cancel'),
confirmButtonColor: "#ed5565",
confirmButtonText: gettext('Confirm'),
closeOnConfirm: true
}, function () {
doDelete();
});
}
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
function makeLabel(data) {
return "<label class='detail-key'><b>" + data[0] + ": </b></label> " + data[1] + "</br>"
}
function parseTableFilter(value) {
var cleanValues = [];
if (!value) {
return {}
}
var valuesArray = value.split(':');
for (var i=0; i<valuesArray.length; i++) {
var v = valuesArray[i].trim();
if (!v) {
continue
}
// 如果是最后一个元素直接push不需要再处理了, 因为最后一个肯定不是key
if (i === valuesArray.length -1) {
cleanValues.push(v);
continue
}
v = v.split(' ');
// 如果长度是1直接push上
// 如果长度不是1根据空格分隔后最后面的是key
if (v.length === 1) {
cleanValues.push(v[0]);
} else {
var leaveData = v.slice(0, -1).join(' ').trim();
cleanValues.push(leaveData);
cleanValues.push(v.slice(-1)[0]);
}
}
var filter = {};
var key = '';
for (i=0; i<cleanValues.length; i++) {
if (i%2 === 0) {
key = cleanValues[i]
} else {
value = cleanValues[i];
filter[key] = value
}
}
return filter;
}
var jumpserver = {};
jumpserver.checked = false;
jumpserver.selected = {};
jumpserver.language = {
processing: gettext('Loading') + '...',
search: gettext('Search'),
select: {
rows: {
_: gettext("Selected item %d"),
0: ""
}
},
lengthMenu: gettext("Per page _MENU_"),
info: gettext('Displays the results of items _START_ to _END_; A total of _TOTAL_ entries'),
infoFiltered: "",
infoEmpty: "",
zeroRecords: gettext("No match"),
emptyTable: gettext('No record'),
paginate: {
first: "«",
previous: "",
next: "",
last: "»"
}
};
function setDataTablePagerLength(num) {
$.fn.DataTable.ext.pager.numbers_length = num;
}
jumpserver.initDataTable = function (options) {
// options = {
// ele *: $('#dataTable_id'),
// ajax_url *: '{% url 'users:user-list-api' %}',
// columns *: [{data: ''}, ....],
// dom: 'fltip',
// i18n_url: '{% static "js/...../en-us.json" %}',
// order: [[1, 'asc'], [2, 'asc'], ...],
// buttons: ['excel', 'pdf', 'print'],
// columnDefs: [{target: 0, createdCell: ()=>{}}, ...],
// uc_html: '<a>header button</a>',
// op_html: 'div.btn-group?',
// paging: true
// }
setDataTablePagerLength(5);
var ele = options.ele || $('.dataTable');
var columnDefs = [
{
targets: 0,
orderable: false,
width: "20px",
createdCell: function (td, 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'
}
];
columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs;
var select = {
style: 'multi',
selector: 'td:first-child'
};
var table = ele.DataTable({
pageLength: options.pageLength || 15,
dom: options.dom || '<"#uc.pull-left"><"pull-right"<"inline"l><"#fb.inline"><"inline"f><"#fa.inline">>tr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
order: options.order || [],
// select: options.select || 'multi',
searchDelay: 800,
buttons: [],
columnDefs: columnDefs,
ajax: {
url: options.ajax_url,
dataSrc: ""
},
columns: options.columns || [],
select: options.select || select,
language: jumpserver.language,
lengthMenu: [[10, 15, 25, 50, -1], [10, 15, 25, 50, "All"]]
});
table.on('select', function (e, dt, type, indexes) {
var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', true);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true
}).on('deselect', function (e, dt, type, indexes) {
var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', false);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false
}).on('draw', function () {
$('#op').html(options.op_html || '');
$('#uc').html(options.uc_html || '');
$('[data-toggle="popover"]').popover({
html: true,
placement: 'bottom',
trigger: 'click',
container: 'body'
}).on('click', function (e) {
$('[data-toggle="popover"]').not(this).popover('hide');
});
});
$('.ipt_check_all').on('click', function () {
if ($(this).prop("checked")) {
$(this).closest('table').find('.ipt_check').prop('checked', true);
jumpserver.checked = true;
table.rows({search: 'applied', page: 'current'}).select();
} else {
$(this).closest('table').find('.ipt_check').prop('checked', false);
jumpserver.checked = false;
table.rows({search: 'applied', page: 'current'}).deselect();
}
});
return table;
};
jumpserver.initStaticTable = function (selector) {
$(selector).DataTable({
"searching": false,
"bInfo": false,
"paging": false,
"order": [],
"language": jumpserver.language
});
};
jumpserver.initServerSideDataTable = function (options) {
// options = {
// ele *: $('#dataTable_id'),
// ajax_url *: '{% url 'users:user-list-api' %}',
// select_style: 'multi',
// columns *: [{data: ''}, ....],
// dom: 'fltip',
// i18n_url: '{% static "js/...../en-us.json" %}',
// order: [[1, 'asc'], [2, 'asc'], ...],
// buttons: ['excel', 'pdf', 'print'],
// columnDefs: [{target: 0, createdCell: ()=>{}}, ...],
// uc_html: '<a>header button</a>',
// op_html: 'div.btn-group?',
// paging: true,
// paging_numbers_length: 5;
// hideDefaultDefs: false;
// }
var pagingNumbersLength = 5;
if (options.paging_numbers_length){
pagingNumbersLength = options.paging_numbers_length;
}
setDataTablePagerLength(pagingNumbersLength);
var ele = options.ele || $('.dataTable');
var columnDefs = [
{
targets: 0,
orderable: false,
width: "20px",
createdCell: function (td, cellData) {
var data = '<input type="checkbox" class="text-center ipt_check" id=Id>'.replace('Id', cellData);
$(td).html(data);
}
},
{
targets: '_all',
className: 'text-center',
render: $.fn.dataTable.render.text()
}
];
if (options.hideDefaultDefs) {
columnDefs = [];
}
var select_style = options.select_style || 'multi';
columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs;
var select = {
style: select_style,
selector: 'td:first-child'
};
var dom = '<"#uc.pull-left"> <"pull-right"<"#lb.inline"> <"inline"l> <"#fb.inline"> <"inline"f><"#fa.inline">>' +
'tr' +
'<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>';
var table = ele.DataTable({
pageLength: options.pageLength || 15,
// dom: options.dom || '<"#uc.pull-left">fltr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
// dom: options.dom || '<"#uc.pull-left"><"pull-right"<"inline"l><"#fb.inline"><"inline"<"table-filter"f>><"#fa.inline">>tr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
dom: options.dom || dom,
order: options.order || [],
buttons: [],
columnDefs: columnDefs,
serverSide: true,
processing: true,
searchDelay: 800,
oSearch: options.oSearch,
ajax: {
url: options.ajax_url,
error: function (jqXHR, textStatus, errorThrown) {
if (jqXHR.responseText && jqXHR.responseText.indexOf("%(value)s") !== -1 ) {
return
}
var msg = gettext("Unknown error occur");
if (jqXHR.responseJSON) {
if (jqXHR.responseJSON.error) {
msg = jqXHR.responseJSON.error
} else if (jqXHR.responseJSON.msg) {
msg = jqXHR.responseJSON.msg
}
}
alert(msg)
},
data: function (data) {
delete data.columns;
if (data.length !== null) {
data.limit = data.length;
delete data.length;
}
if (data.start !== null) {
data.offset = data.start;
delete data.start;
}
if (data.search !== null) {
var searchValue = data.search.value;
var searchFilter = parseTableFilter(searchValue);
if (Object.keys(searchFilter).length === 0) {
data.search = searchValue;
} else {
data.search = '';
$.each(searchFilter, function (k, v) {
data[k] = v
})
}
}
if (data.order !== null && data.order.length === 1) {
var col = data.order[0].column;
var order = options.columns[col].data;
if (data.order[0].dir === "desc") {
order = "-" + order;
}
data.order = order;
}
},
dataFilter: function (data) {
var json = jQuery.parseJSON(data);
json.recordsTotal = json.count;
json.recordsFiltered = json.count;
return JSON.stringify(json); // return JSON string
},
dataSrc: "results"
},
columns: options.columns || [],
select: options.select || select,
language: jumpserver.language,
lengthMenu: options.lengthMenu || [[15, 25, 50, 9999], [15, 25, 50, 'All']]
});
table.selected = [];
table.selected_rows = [];
table.on('select', function (e, dt, type, indexes) {
var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', true);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true;
if (type === 'row') {
var rows = table.rows(indexes).data();
$.each(rows, function (id, row) {
if (row.id && $.inArray(row.id, table.selected) === -1) {
if (select.style === 'multi'){
table.selected.push(row.id);
table.selected_rows.push(row);
}
else{
table.selected = [row.id];
table.selected_rows = [row];
}
}
})
}
}).on('deselect', function (e, dt, type, indexes) {
var $node = table[type](indexes).nodes().to$();
$node.find('input.ipt_check').prop('checked', false);
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false;
if (type === 'row') {
var rows = table.rows(indexes).data();
$.each(rows, function (id, row) {
if (row.id) {
var index = table.selected.indexOf(row.id);
if (index > -1) {
table.selected.splice(index, 1);
table.selected_rows.splice(index, 1);
}
}
})
}
}).on('draw', function () {
$('[data-toggle="popover"]').popover({
html: true,
placement: 'bottom',
trigger: 'click',
container: 'body'
}).on('click', function (e) {
$('[data-toggle="popover"]').not(this).popover('hide');
});
var table_data = [];
$.each(table.rows().data(), function (id, row) {
if (row.id) {
table_data.push(row.id)
}
});
$.each(table.selected, function (id, data) {
var index = table_data.indexOf(data);
if (index > -1) {
table.rows(index).select()
}
});
}).on("init", function () {
$('#op').html(options.op_html || '');
$('#uc').html(options.uc_html || '');
$('#fb').html(options.fb_html || '');
$('#fa').html(options.fa_html || '');
$('#lb').html(options.lb_html || '');
});
var table_id = table.settings()[0].sTableId;
$('#' + table_id + ' .ipt_check_all').on('click', function () {
if (select_style !== 'multi') {
return
}
if ($(this).prop("checked")) {
$(this).closest('table').find('.ipt_check').prop('checked', true);
table.rows({search: 'applied', page: 'current'}).select();
} else {
$(this).closest('table').find('.ipt_check').prop('checked', false);
table.rows({search: 'applied', page: 'current'}).deselect();
}
});
// jumpserver.table = table;
return table;
};
/**
* 替换所有匹配exp的字符串为指定字符串
* @param exp 被替换部分的正则
* @param newStr 替换成的字符串
*/
String.prototype.replaceAll = function (exp, newStr) {
return this.replace(new RegExp(exp, "gm"), newStr);
};
/**
* 原型字符串格式化
* @param args 格式化参数值
*/
String.prototype.format = function (args) {
var result = this;
if (arguments.length < 1) {
return result;
}
var data = arguments;
if (arguments.length == 1 && typeof (args) == "object") {
data = args;
}
for (var key in data) {
var value = data[key];
if (undefined != value) {
result = result.replaceAll("\\{" + key + "\\}", value);
}
}
return result;
};
function setCookie(key, value, time) {
var expires = new Date();
if (!time) {
time = expires.getTime() + (24 * 60 * 60 * 1000);
}
expires.setTime(time);
document.cookie = key + '=' + value + ';expires=' + expires.toUTCString() + ';path=/';
}
function delCookie(key) {
var expires = new Date();
expires.setTime(expires.getTime() - 1);
var val = getCookie(key);
if (val !== null) {
document.cookie = key + '=' + val + ";expires" + expires.toUTCString() + ';path=/';
}
}
function createPopover(dataset, title, callback) {
if (callback !== undefined) {
var new_dataset = [];
$.each(dataset, function (index, value) {
new_dataset.push(callback(value))
});
dataset = new_dataset;
}
var data_content = dataset.join("<br>");
var html = "<a data-toggle='popover' data-content='" + data_content + "'>" + dataset.length + "</a>";
return html;
}
$(function () {
(function ($) {
$.getUrlParam = function (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
})(jQuery);
});
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
function setUrlParam(url, name, value) {
var urlArray = url.split("?");
if (urlArray.length === 1) {
url += "?" + name + "=" + value;
} else {
var oriParam = urlArray[1].split("&");
var oriParamMap = {};
$.each(oriParam, function (index, value) {
var v = value.split("=");
oriParamMap[v[0]] = v[1];
});
oriParamMap[name] = value;
url = urlArray[0] + "?";
var newParam = [];
$.each(oriParamMap, function (index, value) {
newParam.push(index + "=" + value);
});
url += newParam.join("&")
}
return url
}
// Password check rules
var rules_short_map_id = {
'min': 'id_security_password_min_length',
'upper': 'id_security_password_upper_case',
'lower': 'id_security_password_lower_case',
'number': 'id_security_password_number',
'special': 'id_security_password_special_char'
};
var rules_id_map_label = {
'id_security_password_min_length': gettext('Password minimum length {N} bits'),
'id_security_password_upper_case': gettext('Must contain capital letters'),
'id_security_password_lower_case': gettext('Must contain lowercase letters'),
'id_security_password_number': gettext('Must contain numeric characters'),
'id_security_password_special_char': gettext('Must contain special characters')
};
function getRuleLabel(rule) {
var label = '';
if (rule.key === rules_short_map_id['min']) {
label = rules_id_map_label[rule.key].replace('{N}', rule.value)
} else {
label = rules_id_map_label[rule.key]
}
return label
}
// 校验密码-改变规则颜色
function checkPasswordRules(password, minLength) {
if (wordMinLength(password, minLength)) {
$('#' + rules_short_map_id['min']).css('color', 'green')
} else {
$('#' + rules_short_map_id['min']).css('color', '#908a8a')
}
if (wordUpperCase(password)) {
$('#' + rules_short_map_id['upper']).css('color', 'green')
} else {
$('#' + rules_short_map_id['upper']).css('color', '#908a8a')
}
if (wordLowerCase(password)) {
$('#' + rules_short_map_id['lower']).css('color', 'green')
} else {
$('#' + rules_short_map_id['lower']).css('color', '#908a8a')
}
if (wordNumber(password)) {
$('#' + rules_short_map_id['number']).css('color', 'green')
} else {
$('#' + rules_short_map_id['number']).css('color', '#908a8a')
}
if (wordSpecialChar(password)) {
$('#' + rules_short_map_id['special']).css('color', 'green')
} else {
$('#' + rules_short_map_id['special']).css('color', '#908a8a')
}
}
// 最小长度
function wordMinLength(word, minLength) {
//var minLength = {{ min_length }};
var re = new RegExp("^(.{" + minLength + ",})$");
return word.match(re)
}
// 大写字母
function wordUpperCase(word) {
return word.match(/([A-Z]+)/)
}
// 小写字母
function wordLowerCase(word) {
return word.match(/([a-z]+)/)
}
// 数字字符
function wordNumber(word) {
return word.match(/([\d]+)/)
}
// 特殊字符
function wordSpecialChar(word) {
return word.match(/[`,~,!,@,#,\$,%,\^,&,\*,\(,\),\-,_,=,\+,\{,\},\[,\],\|,\\,;,',:,",\,,\.,<,>,\/,\?]+/)
}
// 显示弹窗密码规则
function popoverPasswordRules(password_check_rules, $el) {
var message = "";
jQuery.each(password_check_rules, function (idx, rule) {
message += "<li id=" + rule.key + " style='list-style-type:none;'> <i class='fa fa-check-circle-o' style='margin-right:10px;' ></i>" + getRuleLabel(rule) + "</li>";
});
//$('#id_password_rules').html(message);
$el.html(message)
}
// 初始化弹窗popover
function initPopover($container, $progress, $idPassword, $el, password_check_rules, i18n_fallback) {
options = {};
// User Interface
options.ui = {
container: $container,
viewports: {
progress: $progress
//errors: $('.popover-content')
},
showProgressbar: true,
showVerdictsInsideProgressBar: true
};
options.i18n = {
fallback: i18n_fallback,
t: function (key) {
var result = '';
result = options.i18n.fallback[key];
return result === key ? '' : result;
}
};
$idPassword.pwstrength(options);
popoverPasswordRules(password_check_rules, $el);
}
function rootNodeAddDom(ztree, callback) {
var refreshIcon = "<a id='tree-refresh'><i class='fa fa-refresh'></i></a>";
var rootNode = ztree.getNodes()[0];
if (rootNode) {
var $rootNodeRef = $("#" + rootNode.tId + "_a");
$rootNodeRef.after(refreshIcon);
} else {
$rootNodeRef = $('#' + ztree.setting.treeId);
$rootNodeRef.html(refreshIcon);
}
var refreshIconRef = $('#tree-refresh');
refreshIconRef.bind('click', function () {
ztree.destroy();
callback()
})
}
function APIExportCSV(props) {
/*
{
listUrl:
objectsId:
template:
table:
params:
}
*/
var _listUrl = props.listUrl;
var _objectsId = props.objectsId;
var _template = props.template;
var _table = props.table;
var _params = props.params || {};
var tableParams = _table.ajax.params();
var exportUrl = setUrlParam(_listUrl, 'format', 'csv');
if (_template) {
exportUrl = setUrlParam(exportUrl, 'template', _template)
}
for (var k in tableParams) {
if (datatableInternalParams.includes(k)) {
continue
}
if (!tableParams[k]) {
continue
}
exportUrl = setUrlParam(exportUrl, k, tableParams[k])
}
for (var k in _params) {
exportUrl = setUrlParam(exportUrl, k, tableParams[k])
}
if (!_objectsId) {
console.log(exportUrl);
window.open(exportUrl);
return
}
requestApi({
url: '/api/v1/common/resources/cache/',
data: JSON.stringify({resources: _objectsId}),
method: "POST",
flash_message: false,
success: function (data) {
exportUrl = setUrlParam(exportUrl, 'spm', data.spm);
console.log(exportUrl);
window.open(exportUrl);
},
failed: function () {
toastr.error(gettext('Export failed'));
}
});
}
function APIExportData(props) {
props = props || {};
$.ajax({
url: '/api/common/v1/resources/cache/',
type: props.method || "POST",
data: props.body,
contentType: props.content_type || "application/json; charset=utf-8",
dataType: props.data_type || "json",
success: function (data) {
var export_url = props.success_url;
var params = props.params || {};
params['format'] = props.format;
params['spm'] = data.spm;
for (var k in params) {
export_url = setUrlParam(export_url, k, params[k])
}
window.open(export_url);
},
error: function () {
toastr.error(gettext('Export failed'));
}
})
}
function APIImportData(props) {
props = props || {};
$.ajax({
url: props.url,
type: props.method || "POST",
processData: false,
data: props.body,
contentType: props.content_type || 'text/csv',
success: function (data) {
if (props.method === 'POST') {
$('#created_failed').html('');
$('#created_failed_detail').html('');
$('#success_created').html(gettext("Import Success"));
$('#success_created_detail').html("Count" + ": " + data.length);
} else {
$('#updated_failed').html('');
$('#updated_failed_detail').html('');
$('#success_updated').html(gettext("Update Success"));
$('#success_updated_detail').html(gettext("Count") + ": " + data.length);
}
props.data_table.ajax.reload()
},
error: function (error) {
var data = error.responseJSON;
console.log(data);
if (data instanceof Array) {
var html = '';
var li = '';
var err = '';
$.each(data, function (index, item) {
err = '';
for (var prop in item) {
err += prop + ": " + item[prop][0] + " "
}
if (err) {
li = "<li>" + "Line " + (++index) + ". " + err + "</li>";
html += li
}
});
html = "<ul>" + html + "</ul>"
} else {
html = error.responseText
}
if (props.method === 'POST') {
$('#success_created').html('');
$('#success_created_detail').html('');
$('#created_failed').html(gettext("Import failed"));
$('#created_failed_detail').html(html);
} else {
$('#success_updated').html('');
$('#success_updated_detail').html('');
$('#updated_failed').html(gettext("Update failed"));
$('#updated_failed_detail').html(html);
}
}
})
}
function htmlEscape(d) {
return typeof d === 'string' ?
d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
d;
}
function objectAttrsIsList(obj, attrs) {
attrs.forEach(function (attr) {
if (!obj[attr]) {
obj[attr] = []
} else if (obj[attr] && !(obj[attr] instanceof Array)) {
obj[attr] = [obj[attr]]
}
})
}
function objectAttrsIsDatetime(obj, attrs) {
attrs.forEach(function (attr) {
obj[attr] = toSafeDateISOStr(obj[attr]);
})
}
function objectAttrsIsBool(obj, attrs) {
attrs.forEach(function (attr) {
if (!obj[attr]) {
obj[attr] = false
} else {
obj[attr] = ['on', '1', 'true', 'True'].includes(obj[attr]);
}
})
}
function objectAttrsIsNumber(obj, attrs) {
attrs.forEach(function (attr) {
if (!obj[attr]) {
obj[attr] = null;
}
})
}
function cleanDateStr(d) {
for (var i = 0; i < 3; i++) {
if (!isNaN(Date.parse(d))) {
return d;
}
if (!isNaN(Number(d))) {
return d;
}
switch (i) {
case 0:
d = d.replaceAll('-', '/');
break;
case 1:
d = d.split('+')[0].trimRight();
break;
}
}
return null;
}
function safeDate(s) {
s = cleanDateStr(s);
return new Date(s)
}
function toSafeDateISOStr(s) {
var d = safeDate(s);
return d.toISOString();
}
function toSafeLocalDateStr(d) {
var date = safeDate(d);
// var date_s = date.toLocaleString(getUserLang(), {hour12: false});
var date_s = date.toLocaleString(getUserLang(), {hourCycle: "h23"});
return date_s.split("/").join('-')
}
function getUrlParams(url) {
url = url.split("?");
var params = "";
if (url.length === 2) {
params = url[1];
}
return params
}
function getTimeUnits(u) {
var units = {
"d": "",
"h": "",
"m": "",
"s": "",
};
if (getUserLang() === "zh-CN") {
return units[u]
}
return u
}
function timeOffset(a, b) {
var start = safeDate(a);
var end = safeDate(b);
var offset = (end - start) / 1000;
return readableSecond(offset)
}
function readableSecond(offset) {
var days = offset / 3600 / 24;
var hours = offset / 3600;
var minutes = offset / 60;
var seconds = offset;
if (days > 1) {
return days.toFixed(1) + " " + getTimeUnits("d");
} else if (hours > 1) {
return hours.toFixed(1) + " " + getTimeUnits("h");
} else if (minutes > 1) {
return minutes.toFixed(1) + " " + getTimeUnits("m")
} else if (seconds > 1) {
return seconds.toFixed(1) + " " + getTimeUnits("s")
}
return ""
}
function readFile(ref) {
var files = ref.prop('files');
var hasFile = files && files.length > 0;
if (hasFile) {
var reader = new FileReader();//新建一个FileReader
reader.readAsText(files[0], "UTF-8");//读取文件
reader.onload = function (evt) { //读取完文件之后会回来这里
ref.trigger("onload", evt.target.result);
};
} else {
ref.trigger("onload", null);
}
return ref
}
function select2AjaxInit(option) {
/*
{
selector:
url: ,
disabledData: ,
displayFormat,
idFormat,
}
*/
var selector = option.selector;
var url = option.url;
var disabledData = option.disabledData;
var displayFormat = option.displayFormat || function (data) {
return data.name;
};
var idFormat = option.idFormat || function (data) {
return data.id;
};
return $(selector).select2({
closeOnSelect: false,
ajax: {
url: url,
data: function (params) {
var page = params.page || 1;
var query = {
search: params.term,
offset: (page - 1) * 10,
limit: 10
};
return query
},
processResults: function (data) {
var results = $.map(data.results, function (v, i) {
var display = displayFormat(v);
var id = idFormat(v);
var d = {id: id, text: display};
if (disabledData && disabledData.indexOf(v.id) !== -1) {
d.disabled = true;
}
return d;
});
var more = !!data.next;
return {results: results, pagination: {"more": more}}
}
},
})
}
function usersSelect2Init(selector, url, disabledData) {
if (!url) {
url = '/api/v1/users/users/'
}
function displayFormat(v) {
return v.name + '(' + v.username +')';
}
var option = {
url: url,
selector: selector,
disabledData: disabledData,
displayFormat: displayFormat
};
return select2AjaxInit(option)
}
function nodesSelect2Init(selector, url, disabledData) {
if (!url) {
url = '/api/v1/assets/nodes/'
}
function displayFormat(v) {
return v.full_value;
}
var option = {
url: url,
selector: selector,
disabledData: disabledData,
displayFormat: displayFormat
};
return select2AjaxInit(option)
}
function showCeleryTaskLog(taskId) {
var url = '/ops/celery/task/taskId/log/'.replace('taskId', taskId);
window.open(url, '', 'width=900,height=600')
}
function getUserLang(){
let userLangEN = document.cookie.indexOf('django_language=en');
if (userLangEN === -1){
return 'zh-CN'
}
else{
return 'en-US'
}
}
function initDateRangePicker(selector, options) {
if (!options) {
options = {}
}
var zhLocale = {
format: 'YYYY-MM-DD HH:mm',
separator: ' ~ ',
applyLabel: "应用",
cancelLabel: "取消",
resetLabel: "重置",
daysOfWeek: ["", "", "", "", "", "", ""],//汉化处理
monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
};
var enLocale = {
format: "YYYY-MM-DD HH:mm",
separator: " - ",
applyLabel: "Apply",
cancelLabel: "Cancel",
resetLabel: "Reset",
daysOfWeek: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
};
var defaultOption = {
singleDatePicker: true,
showDropdowns: true,
timePicker: true,
timePicker24Hour: true,
autoApply: true,
};
if (getUserLang() === 'zh-CN') {
defaultOption.locale = zhLocale;
}
else{
// en-US
defaultOption.locale = enLocale;
}
options = Object.assign(defaultOption, options);
return $(selector).daterangepicker(options);
}
function reloadPage() {
setTimeout( function () {window.location.reload();}, 300);
}
function isEmptyObject(obj) {
return Object.keys(obj).length === 0
}
function getStatusIcon(status, mapping, title) {
var navy = '<i class="fa fa-circle text-navy" title=""></i>';
var danger = '<i class="fa fa-circle text-danger" title=""></i>';
var warning = '<i class="fa fa-circle text-warning" title=""></i>';
var icons = {
navy: navy,
danger: danger,
warning: warning
};
var defaultMapping = {
true: 'navy',
false: 'danger',
1: 'navy',
0: 'danger',
default: 'navy'
};
if (!mapping) {
mapping = defaultMapping;
}
var name = mapping[status] || mapping['default'];
var icon = icons[name];
if (title) {
icon = icon.replace('title=""', 'title="' + title + '"')
}
return icon;
}
function fillKey(key) {
let keySize = 128
// 如果超过 key 16 , 最大取 32 需要更改填充
if (key.length > 16) {
key = key.slice(0, 32)
keySize = keySize * 2
}
const filledKeyLength = keySize / 8
if (key.length >= filledKeyLength) {
return key.slice(0, filledKeyLength)
}
const filledKey = Buffer.alloc(keySize / 8)
const keys = Buffer.from(key)
for (let i = 0; i < keys.length; i++) {
filledKey[i] = keys[i]
}
return filledKey
}
function aesEncrypt(text, originKey) {
const key = CryptoJS.enc.Utf8.parse(fillKey(originKey));
return CryptoJS.AES.encrypt(text, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.ZeroPadding
}).toString();
}
function rsaEncrypt(text, pubKey) {
if (!text) {
return text
}
const jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(pubKey);
return jsEncrypt.encrypt(text);
}
function rsaDecrypt(cipher, pkey) {
const jsEncrypt = new JSEncrypt();
jsEncrypt.setPrivateKey(pkey);
return jsEncrypt.decrypt(cipher)
}
window.rsaEncrypt = rsaEncrypt
window.rsaDecrypt = rsaDecrypt
function encryptPassword(password) {
if (!password) {
return ''
}
const aesKey = (Math.random() + 1).toString(36).substring(2)
// public key base64 存储的
const rsaPublicKeyText = getCookie('jms_public_key')
.replaceAll('"', '')
const rsaPublicKey = atob(rsaPublicKeyText)
const keyCipher = rsaEncrypt(aesKey, rsaPublicKey)
const passwordCipher = aesEncrypt(password, aesKey)
return `${keyCipher}:${passwordCipher}`
}
function randomString(length) {
const characters ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
const charactersLength = characters.length;
for ( let i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function testEncrypt() {
const radio = []
const len2 = []
for (let i=1;i<4096;i++) {
const password = randomString(i)
const cipher = encryptPassword(password)
len2.push([password.length, cipher.length])
radio.push(cipher.length/password.length)
}
return radio
}
window.encryptPassword = encryptPassword