diff --git a/apps/authentication/models.py b/apps/authentication/models.py index bc92eb8b5..f50305651 100644 --- a/apps/authentication/models.py +++ b/apps/authentication/models.py @@ -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) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 6f724f936..fe18ec6df 100644 Binary files a/apps/locale/zh/LC_MESSAGES/django.mo and b/apps/locale/zh/LC_MESSAGES/django.mo differ diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 0f18de91d..3d36fc15e 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -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 \n" "Language-Team: Jumpserver team\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 "" -#| "
Luna is a separately deployed program, you need to deploy Luna, " -#| "koko, configure nginx for url distribution,
If you see this " -#| "page, prove that you are not accessing the nginx listening port. Good " -#| "luck." msgid "" "
Koko is a separately deployed program, you need to deploy Koko, " "configure nginx for url distribution,
If you see this page, " "prove that you are not accessing the nginx listening port. Good luck." msgstr "" -"
Luna是单独部署的一个程序,你需要部署luna,koko,
如果你看到了" +"
Koko是单独部署的一个程序,你需要部署Koko, 并确保nginx配置转发,
如果你看到了" "这个页面,证明你访问的不是nginx监听的端口,祝你好运
" #: 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" +"
\n" +"

Your has a new order

\n" +"
\n" +" Title: {order.title}\n" +"
\n" +" User: {user}\n" +"
\n" +" City: {order.city}\n" +"
\n" +" IP: {order.ip}\n" +"
\n" +" click here to review \n" +"
\n" +"
\n" +" " +msgstr "" +"\n" +"
\n" +"

您有一个新工单

\n" +"
\n" +" 标题: {order.title}\n" +"
\n" +" 用户: {user}\n" +"
\n" +" 城市: {order.city}\n" +"
\n" +" IP: {order.ip}\n" +"
\n" +" 点我查看 \n" +"
\n" +"
\n" +" " + #: orders/templates/orders/login_confirm_order_detail.html:75 msgid "ago" msgstr "前" diff --git a/apps/orders/api.py b/apps/orders/api.py index a588dd684..aec04ad46 100644 --- a/apps/orders/api.py +++ b/apps/orders/api.py @@ -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): diff --git a/apps/orders/templates/orders/login_confirm_order_list.html b/apps/orders/templates/orders/login_confirm_order_list.html index e21fb8c9f..e7b8da90c 100644 --- a/apps/orders/templates/orders/login_confirm_order_list.html +++ b/apps/orders/templates/orders/login_confirm_order_list.html @@ -1,7 +1,8 @@ {% extends '_base_list.html' %} {% load i18n static %} {% block table_search %} - +{% endblock %} +{% block custom_head_css_js %} {% endblock %} {% block table_container %} @@ -22,6 +23,7 @@
+{% 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) diff --git a/apps/static/css/jumpserver.css b/apps/static/css/jumpserver.css index 02e738d24..ffcb87d33 100644 --- a/apps/static/css/jumpserver.css +++ b/apps/static/css/jumpserver.css @@ -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; +} diff --git a/apps/static/js/jumpserver.js b/apps/static/js/jumpserver.js index edea12c5b..89ac43364 100644 --- a/apps/static/js/jumpserver.js +++ b/apps/static/js/jumpserver.js @@ -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) { diff --git a/apps/templates/_filter_dropdown.html b/apps/templates/_filter_dropdown.html new file mode 100644 index 000000000..e99ca79ef --- /dev/null +++ b/apps/templates/_filter_dropdown.html @@ -0,0 +1,81 @@ + + +