mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-07-06 11:36:32 +00:00
[Update] 修改工单
This commit is contained in:
parent
d0ba67ed50
commit
fe235823b4
@ -50,7 +50,7 @@ class LoginConfirmSetting(CommonModelMixin):
|
|||||||
|
|
||||||
def create_confirm_order(self, request=None):
|
def create_confirm_order(self, request=None):
|
||||||
from orders.models import LoginConfirmOrder
|
from orders.models import LoginConfirmOrder
|
||||||
title = _('User login request: {}'.format(self.user))
|
title = _('User login confirm: {}'.format(self.user))
|
||||||
if request:
|
if request:
|
||||||
remote_addr = get_request_ip(request)
|
remote_addr = get_request_ip(request)
|
||||||
city = get_ip_city(remote_addr)
|
city = get_ip_city(remote_addr)
|
||||||
|
Binary file not shown.
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Jumpserver 0.3.3\n"
|
"Project-Id-Version: Jumpserver 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-30 11:52+0800\n"
|
"POT-Creation-Date: 2019-10-30 14:51+0800\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
|
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
|
||||||
@ -2534,8 +2534,8 @@ msgid "review_login_confirmation_settings"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: authentication/models.py:53
|
#: authentication/models.py:53
|
||||||
msgid "User login request: {}"
|
msgid "User login confirm: {}"
|
||||||
msgstr "用户登录请求: {}"
|
msgstr "用户登录复核: {}"
|
||||||
|
|
||||||
#: authentication/models.py:57
|
#: authentication/models.py:57
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -2833,18 +2833,12 @@ msgid "Websocket server run on port: {}, you should proxy it on nginx"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: jumpserver/views.py:241
|
#: jumpserver/views.py:241
|
||||||
#, fuzzy
|
|
||||||
#| msgid ""
|
|
||||||
#| "<div>Luna is a separately deployed program, you need to deploy Luna, "
|
|
||||||
#| "koko, configure nginx for url distribution,</div> </div>If you see this "
|
|
||||||
#| "page, prove that you are not accessing the nginx listening port. Good "
|
|
||||||
#| "luck.</div>"
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"<div>Koko is a separately deployed program, you need to deploy Koko, "
|
"<div>Koko is a separately deployed program, you need to deploy Koko, "
|
||||||
"configure nginx for url distribution,</div> </div>If you see this page, "
|
"configure nginx for url distribution,</div> </div>If you see this page, "
|
||||||
"prove that you are not accessing the nginx listening port. Good luck.</div>"
|
"prove that you are not accessing the nginx listening port. Good luck.</div>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<div>Luna是单独部署的一个程序,你需要部署luna,koko, </div><div>如果你看到了"
|
"<div>Koko是单独部署的一个程序,你需要部署Koko, 并确保nginx配置转发, </div><div>如果你看到了"
|
||||||
"这个页面,证明你访问的不是nginx监听的端口,祝你好运</div>"
|
"这个页面,证明你访问的不是nginx监听的端口,祝你好运</div>"
|
||||||
|
|
||||||
#: ops/api/celery.py:54
|
#: ops/api/celery.py:54
|
||||||
@ -2853,7 +2847,7 @@ msgstr "等待任务开始"
|
|||||||
|
|
||||||
#: ops/api/command.py:35
|
#: ops/api/command.py:35
|
||||||
msgid "Not has host {} permission"
|
msgid "Not has host {} permission"
|
||||||
msgstr ""
|
msgstr "没有该主机 {} 权限"
|
||||||
|
|
||||||
#: ops/models/adhoc.py:38
|
#: ops/models/adhoc.py:38
|
||||||
msgid "Interval"
|
msgid "Interval"
|
||||||
@ -3262,6 +3256,51 @@ msgstr "拒绝"
|
|||||||
msgid "this order"
|
msgid "this order"
|
||||||
msgstr "这个工单"
|
msgstr "这个工单"
|
||||||
|
|
||||||
|
#: orders/signals_handler.py:21
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "New node"
|
||||||
|
msgid "New order"
|
||||||
|
msgstr "新节点"
|
||||||
|
|
||||||
|
# msgid "Update user"
|
||||||
|
# msgstr "更新用户"
|
||||||
|
#: orders/signals_handler.py:24
|
||||||
|
#, fuzzy, python-brace-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <div>\n"
|
||||||
|
" <p>Your has a new order</p>\n"
|
||||||
|
" <div>\n"
|
||||||
|
" <b>Title:</b> {order.title}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <b>User:</b> {user}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <b>City:</b> {order.city}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <b>IP:</b> {order.ip}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <a href={url}>click here to review</a> \n"
|
||||||
|
" </div>\n"
|
||||||
|
" </div>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <div>\n"
|
||||||
|
" <p>您有一个新工单</p>\n"
|
||||||
|
" <div>\n"
|
||||||
|
" <b>标题:</b> {order.title}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <b>用户:</b> {user}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <b>城市:</b> {order.city}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <b>IP:</b> {order.ip}\n"
|
||||||
|
" <br/>\n"
|
||||||
|
" <a href={url}>点我查看</a> \n"
|
||||||
|
" </div>\n"
|
||||||
|
" </div>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
#: orders/templates/orders/login_confirm_order_detail.html:75
|
#: orders/templates/orders/login_confirm_order_detail.html:75
|
||||||
msgid "ago"
|
msgid "ago"
|
||||||
msgstr "前"
|
msgstr "前"
|
||||||
|
@ -12,6 +12,7 @@ from .models import LoginConfirmOrder
|
|||||||
class LoginConfirmOrderViewSet(CommonApiMixin, viewsets.ModelViewSet):
|
class LoginConfirmOrderViewSet(CommonApiMixin, viewsets.ModelViewSet):
|
||||||
serializer_class = serializers.LoginConfirmOrderSerializer
|
serializer_class = serializers.LoginConfirmOrderSerializer
|
||||||
permission_classes = (IsValidUser,)
|
permission_classes = (IsValidUser,)
|
||||||
|
filter_fields = ['status', 'title']
|
||||||
search_fields = ['user_display', 'title', 'ip', 'city']
|
search_fields = ['user_display', 'title', 'ip', 'city']
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
{% extends '_base_list.html' %}
|
{% extends '_base_list.html' %}
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
{% block table_search %}
|
{% block table_search %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block custom_head_css_js %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block table_container %}
|
{% block table_container %}
|
||||||
<table class="table table-striped table-bordered table-hover " id="login_confirm_order_list_table" >
|
<table class="table table-striped table-bordered table-hover " id="login_confirm_order_list_table" >
|
||||||
@ -22,6 +23,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{% include '_filter_dropdown.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content_bottom_left %}{% endblock %}
|
{% block content_bottom_left %}{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
@ -30,6 +32,7 @@ var orderTable = 0;
|
|||||||
function initTable() {
|
function initTable() {
|
||||||
var options = {
|
var options = {
|
||||||
ele: $('#login_confirm_order_list_table'),
|
ele: $('#login_confirm_order_list_table'),
|
||||||
|
oSearch: {sSearch: "status:pending"},
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
cellData = htmlEscape(cellData);
|
cellData = htmlEscape(cellData);
|
||||||
@ -79,6 +82,17 @@ function initTable() {
|
|||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
initTable();
|
initTable();
|
||||||
|
$('')
|
||||||
|
var menu = [
|
||||||
|
{title: "IP", value: "ip"},
|
||||||
|
{title: "{% trans 'Title' %}", value: "title"},
|
||||||
|
{title: "{% trans 'Status' %}", value: "status", submenu: [
|
||||||
|
{title: "{% trans 'Pending' %}", value: "pending"},
|
||||||
|
{title: "{% trans 'Accepted' %}", value: "accepted"},
|
||||||
|
{title: "{% trans 'Rejected' %}", value: "rejected"}
|
||||||
|
]}
|
||||||
|
];
|
||||||
|
initTableFilterDropdown('#login_confirm_order_list_table_filter input', menu)
|
||||||
}).on('click', '.expired', function () {
|
}).on('click', '.expired', function () {
|
||||||
var msg = '{% trans "User is expired" %}';
|
var msg = '{% trans "User is expired" %}';
|
||||||
toastr.error(msg)
|
toastr.error(msg)
|
||||||
|
@ -474,3 +474,83 @@ span.select2-selection__placeholder {
|
|||||||
.p-r-5 {
|
.p-r-5 {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu>.dropdown-menu {
|
||||||
|
top: 0;
|
||||||
|
left: 100%;
|
||||||
|
margin-top: -6px;
|
||||||
|
margin-left: -1px;
|
||||||
|
-webkit-border-radius: 0 6px 6px 6px;
|
||||||
|
-moz-border-radius: 0 6px 6px;
|
||||||
|
border-radius: 0 6px 6px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu:hover>.dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu>a:after {
|
||||||
|
display: block;
|
||||||
|
content: " ";
|
||||||
|
float: right;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 0 5px 5px;
|
||||||
|
border-left-color: #ccc;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-right: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu:hover>a:after {
|
||||||
|
border-left-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu.pull-left {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-submenu.pull-left>.dropdown-menu {
|
||||||
|
left: -100px;
|
||||||
|
margin-left: 10px;
|
||||||
|
-webkit-border-radius: 6px 0 6px 6px;
|
||||||
|
-moz-border-radius: 6px 0 6px 6px;
|
||||||
|
border-radius: 6px 0 6px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bootstrap-tagsinput {
|
||||||
|
border: 1px solid #e5e6e7;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 4px 6px;
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.bootstrap-tagsinput {*/
|
||||||
|
/* background-color: #fff;*/
|
||||||
|
/* border: 1px solid #ccc;*/
|
||||||
|
/* box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);*/
|
||||||
|
/* display: inline-block;*/
|
||||||
|
/* color: #555;*/
|
||||||
|
/* vertical-align: middle;*/
|
||||||
|
/* border-radius: 4px;*/
|
||||||
|
/* max-width: 100%;*/
|
||||||
|
/* line-height: 22px;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
.bootstrap-tagsinput input {
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
outline: none;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0 6px;
|
||||||
|
margin: 0;
|
||||||
|
width: auto;
|
||||||
|
height: 22px;
|
||||||
|
max-width: inherit;
|
||||||
|
}
|
||||||
|
@ -611,16 +611,21 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||||||
style: select_style,
|
style: select_style,
|
||||||
selector: 'td:first-child'
|
selector: 'td:first-child'
|
||||||
};
|
};
|
||||||
|
var 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>>';
|
||||||
var table = ele.DataTable({
|
var table = ele.DataTable({
|
||||||
pageLength: options.pageLength || 15,
|
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">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"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 || '<"#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: dom,
|
||||||
order: options.order || [],
|
order: options.order || [],
|
||||||
buttons: [],
|
buttons: [],
|
||||||
columnDefs: columnDefs,
|
columnDefs: columnDefs,
|
||||||
serverSide: true,
|
serverSide: true,
|
||||||
processing: true,
|
processing: true,
|
||||||
searchDelay: 800,
|
searchDelay: 800,
|
||||||
|
oSearch: options.oSearch,
|
||||||
ajax: {
|
ajax: {
|
||||||
url: options.ajax_url,
|
url: options.ajax_url,
|
||||||
error: function (jqXHR, textStatus, errorThrown) {
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
81
apps/templates/_filter_dropdown.html
Normal file
81
apps/templates/_filter_dropdown.html
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<ul class="dropdown-menu multi-level search-help" role="menu" aria-labelledby="dropdownMenu">
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function addItem(menuRef, menuItem, parent) {
|
||||||
|
menuItem.forEach(function (item) {
|
||||||
|
if (item.submenu) {
|
||||||
|
var subItemData = "<li class='dropdown-submenu pull-left'>" +
|
||||||
|
" <a tabindex='-1' class='search-select' href='#'>VALUE</a>" +
|
||||||
|
"</li>";
|
||||||
|
var subItem = $(subItemData.replace('VALUE', item.title));
|
||||||
|
var subMenu = $('<ul class="dropdown-menu"></ul>');
|
||||||
|
addItem(subMenu, item.submenu, item.value);
|
||||||
|
subItem.append(subMenu);
|
||||||
|
menuRef.append(subItem);
|
||||||
|
} else {
|
||||||
|
var itemRef = $('<li><a class="search-item" data-value="VALUE">TITLE</a></li>'
|
||||||
|
.replace('VALUE', item.value)
|
||||||
|
.replace('TITLE', item.title)
|
||||||
|
);
|
||||||
|
if (parent){
|
||||||
|
itemRef.find('a').data('parent', parent)
|
||||||
|
}
|
||||||
|
menuRef.append(itemRef)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function initTableFilterDropdown(selector, menu) {
|
||||||
|
/*
|
||||||
|
menu = [
|
||||||
|
{title: "Title", value: "title"},
|
||||||
|
{title: "Status", value: "status", submenu: [
|
||||||
|
{"title": "xxx", value: "xxxx"}
|
||||||
|
]},
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
var dropdownRef = $(".search-help");
|
||||||
|
addItem(dropdownRef, menu);
|
||||||
|
$(selector).on("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var offset1 = $(selector).offset();
|
||||||
|
var x = offset1.left;
|
||||||
|
var y = offset1.top;
|
||||||
|
var offset = $(".search-help").parent().offset();
|
||||||
|
x -= offset.left;
|
||||||
|
y -= offset.top;
|
||||||
|
x += 18;
|
||||||
|
y += 80;
|
||||||
|
$('.search-help').css({"top":y+"px", "left":x+"px", "position": "absolute"});
|
||||||
|
$('.dropdown-menu.search-help').show();
|
||||||
|
});
|
||||||
|
$('.search-item').on('click', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var keyword = $(selector);
|
||||||
|
var value = $(this).data('value');
|
||||||
|
var oldValue = keyword.val();
|
||||||
|
var newValue = '';
|
||||||
|
var parentValue = $(this).data("parent");
|
||||||
|
var re;
|
||||||
|
|
||||||
|
if (parentValue) {
|
||||||
|
re = new RegExp(parentValue + '\\s*:\\s*\\w+');
|
||||||
|
oldValue = oldValue.replace(re, '');
|
||||||
|
newValue = oldValue + ' ' + parentValue + ':' + value;
|
||||||
|
} else {
|
||||||
|
re = new RegExp(value + '\\s*:\\s*\\w+');
|
||||||
|
oldValue = oldValue.replace(re, '');
|
||||||
|
newValue = oldValue + ' ' + value + ':';
|
||||||
|
}
|
||||||
|
keyword.val(newValue.trim());
|
||||||
|
$('.dropdown-menu.search-help').hide();
|
||||||
|
keyword.trigger('input');
|
||||||
|
keyword.focus()
|
||||||
|
});
|
||||||
|
$(window).on('click', function (e) {
|
||||||
|
dropdownRef.hide();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user