[Update] 修改工单

pull/3428/head
ibuler 2019-10-30 19:30:49 +08:00
parent d0ba67ed50
commit fe235823b4
8 changed files with 234 additions and 14 deletions

View File

@ -50,7 +50,7 @@ class LoginConfirmSetting(CommonModelMixin):
def create_confirm_order(self, request=None):
from orders.models import LoginConfirmOrder
title = _('User login request: {}'.format(self.user))
title = _('User login confirm: {}'.format(self.user))
if request:
remote_addr = get_request_ip(request)
city = get_ip_city(remote_addr)

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\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"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
@ -2534,8 +2534,8 @@ msgid "review_login_confirmation_settings"
msgstr ""
#: authentication/models.py:53
msgid "User login request: {}"
msgstr "用户登录请求: {}"
msgid "User login confirm: {}"
msgstr "用户登录复核: {}"
#: authentication/models.py:57
msgid ""
@ -2833,18 +2833,12 @@ msgid "Websocket server run on port: {}, you should proxy it on nginx"
msgstr ""
#: 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 ""
"<div>Koko is a separately deployed program, you need to deploy 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>"
msgstr ""
"<div>Luna是单独部署的一个程序你需要部署lunakoko, </div><div>如果你看到了"
"<div>Koko是单独部署的一个程序你需要部署Koko, 并确保nginx配置转发, </div><div>如果你看到了"
"这个页面证明你访问的不是nginx监听的端口祝你好运</div>"
#: ops/api/celery.py:54
@ -2853,7 +2847,7 @@ msgstr "等待任务开始"
#: ops/api/command.py:35
msgid "Not has host {} permission"
msgstr ""
msgstr "没有该主机 {} 权限"
#: ops/models/adhoc.py:38
msgid "Interval"
@ -3262,6 +3256,51 @@ msgstr "拒绝"
msgid "this order"
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
msgid "ago"
msgstr "前"

View File

@ -12,6 +12,7 @@ from .models import LoginConfirmOrder
class LoginConfirmOrderViewSet(CommonApiMixin, viewsets.ModelViewSet):
serializer_class = serializers.LoginConfirmOrderSerializer
permission_classes = (IsValidUser,)
filter_fields = ['status', 'title']
search_fields = ['user_display', 'title', 'ip', 'city']
def get_queryset(self):

View File

@ -1,7 +1,8 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}
{% endblock %}
{% block custom_head_css_js %}
{% endblock %}
{% block table_container %}
<table class="table table-striped table-bordered table-hover " id="login_confirm_order_list_table" >
@ -22,6 +23,7 @@
<tbody>
</tbody>
</table>
{% include '_filter_dropdown.html' %}
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
@ -30,6 +32,7 @@ var orderTable = 0;
function initTable() {
var options = {
ele: $('#login_confirm_order_list_table'),
oSearch: {sSearch: "status:pending"},
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
cellData = htmlEscape(cellData);
@ -79,6 +82,17 @@ function initTable() {
$(document).ready(function(){
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 () {
var msg = '{% trans "User is expired" %}';
toastr.error(msg)

View File

@ -474,3 +474,83 @@ span.select2-selection__placeholder {
.p-r-5 {
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;
}

View File

@ -611,16 +611,21 @@ jumpserver.initServerSideDataTable = function (options) {
style: select_style,
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({
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"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 || [],
buttons: [],
columnDefs: columnDefs,
serverSide: true,
processing: true,
searchDelay: 800,
oSearch: options.oSearch,
ajax: {
url: options.ajax_url,
error: function (jqXHR, textStatus, errorThrown) {

View 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>