diff --git a/app/api/routes/routes.py b/app/api/routes/routes.py index c085dfe9..f5326783 100644 --- a/app/api/routes/routes.py +++ b/app/api/routes/routes.py @@ -13,6 +13,7 @@ from app.views.service.views import (ServiceView, ServiceActionView, ServiceBack from app.views.service.haproxy_section_views import ListenSectionView, UserListSectionView, PeersSectionView, \ GlobalSectionView, DefaultsSectionView from app.views.service.lets_encrypt_views import LetsEncryptsView, LetsEncryptView +from app.views.service.haproxy_lists_views import HaproxyListView from app.views.ha.views import HAView, HAVIPView, HAVIPsView from app.views.user.views import UserView, UserGroupView, UserRoles from app.views.udp.views import UDPListener, UDPListeners, UDPListenerActionView @@ -75,6 +76,8 @@ register_api_id_ip(PeersSectionView, 'haproxy_peers_post', '/section/peers', met register_api_id_ip(PeersSectionView, 'haproxy_peers', '/section/peers/', methods=['GET', 'PUT', 'DELETE']) register_api_id_ip(GlobalSectionView, 'haproxy_global', '/section/global', methods=['GET', 'PUT']) register_api_id_ip(DefaultsSectionView, 'haproxy_defaults', '/section/defaults', methods=['GET', 'PUT']) +bp.add_url_rule('/service//list//', view_func=HaproxyListView.as_view('list_get'), methods=['GET']) +bp.add_url_rule('/service//list', view_func=HaproxyListView.as_view('list_post'), methods=['POST', 'PUT', 'DELETE']) bp.add_url_rule('/service///config/list', view_func=ServiceConfigList.as_view('config_list_ip'), methods=['GET']) bp.add_url_rule('/service///config/list', view_func=ServiceConfigList.as_view('config_list'), methods=['GET']) register_api_id_ip(CheckerView, 'checker', '/tools') diff --git a/app/create_db.py b/app/create_db.py index b4e84313..d25403c2 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -692,7 +692,7 @@ def update_db_v_8_1_2(): def update_ver(): try: - Version.update(version='8.1.2').execute() + Version.update(version='8.1.3').execute() except Exception: print('Cannot update version') diff --git a/app/modules/common/common_classes.py b/app/modules/common/common_classes.py index 785f4431..49fc1fa8 100644 --- a/app/modules/common/common_classes.py +++ b/app/modules/common/common_classes.py @@ -4,7 +4,7 @@ from flask import g import app.modules.db.server as server_sql import app.modules.roxywi.common as roxywi_common -from app.modules.roxywi.class_models import ServerRequest, GroupQuery, CredRequest, ChannelRequest +from app.modules.roxywi.class_models import ServerRequest, GroupQuery, CredRequest, ChannelRequest, ListRequest from app.middleware import get_user_params @@ -36,7 +36,7 @@ class SupportClass: @staticmethod @get_user_params() - def return_group_id(body: Union[ServerRequest, CredRequest, GroupQuery, ChannelRequest]): + def return_group_id(body: Union[ServerRequest, CredRequest, GroupQuery, ChannelRequest, ListRequest]): if body.group_id: if g.user_params['role'] == 1: return body.group_id diff --git a/app/modules/config/add.py b/app/modules/config/add.py index 5194434c..9836f4a6 100644 --- a/app/modules/config/add.py +++ b/app/modules/config/add.py @@ -86,26 +86,19 @@ def save_bwlist(list_name: str, list_con: str, color: str, group: str, server_ip lib_path = get_config.get_config_var('main', 'lib_path') list_path = f"{lib_path}/lists/{group}/{color}/{list_name}" path = sql.get_setting('haproxy_dir') + "/" + color - servers = [] + servers = [server_ip] output = '' try: with open(list_path, "w") as file: file.write(list_con) except IOError as e: - return f'error: Cannot save {color} list. {e}' + raise Exception(f'Cannot save {color} list: {e}') - if server_ip != 'all': - servers.append(server_ip) - - masters = server_sql.is_master(server_ip) - for master in masters: - if master[0] is not None: - servers.append(master[0]) - else: - server = roxywi_common.get_dick_permit() - for s in server: - servers.append(s[2]) + masters = server_sql.is_master(server_ip) + for master in masters: + if master[0] is not None: + servers.append(master[0]) for serv in servers: server_mod.ssh_command(serv, f"sudo mkdir {path}") @@ -113,6 +106,7 @@ def save_bwlist(list_name: str, list_con: str, color: str, group: str, server_ip try: config_mod.upload(serv, f'{path}/{list_name}', list_path) except Exception as e: + roxywi_common.logging(serv, f'error: Upload fail: to {serv}: {e}', roxywi=1, login=1) output += f'error: Upload fail: to {serv}: {e} , ' output += f'success: Edited {color} list was uploaded to {serv} , ' diff --git a/app/modules/roxywi/class_models.py b/app/modules/roxywi/class_models.py index 9983bbdc..ec419c66 100644 --- a/app/modules/roxywi/class_models.py +++ b/app/modules/roxywi/class_models.py @@ -517,3 +517,12 @@ class NettoolsRequest(BaseModel): record_type: Optional[Literal['a', 'aaaa', 'caa', 'cname', 'mx', 'ns', 'ptr', 'sao', 'src', 'txt']] = None ip: Optional[IPvAnyAddress] = None netmask: Optional[int] = None + + +class ListRequest(BaseModel): + server_ip: Optional[Union[IPvAnyAddress, DomainName]] = None + color: Literal['white', 'black'] + name: EscapedString + action: Optional[Literal['reload', 'restart', 'save']] = None + content: Optional[str] = '' + group_id: Optional[int] = None diff --git a/app/modules/roxywi/nettools.py b/app/modules/roxywi/nettools.py index 311d04eb..f1ddbe68 100644 --- a/app/modules/roxywi/nettools.py +++ b/app/modules/roxywi/nettools.py @@ -47,7 +47,7 @@ def ping_from_server(server_from: str, server_to: str, action: str) -> Response: return Response(stream_with_context(paint_output(ssh_generator.generate(action_for_sending))), mimetype='text/html') -def telnet_from_server(server_from: str, server_to: str, port_to: str) -> str: +def telnet_from_server(server_from: str, server_to: str, port_to: int) -> str: count_string = 0 stderr = '' output1 = '' diff --git a/app/modules/service/installation.py b/app/modules/service/installation.py index 9f714d72..16638e3a 100644 --- a/app/modules/service/installation.py +++ b/app/modules/service/installation.py @@ -127,7 +127,7 @@ def generate_haproxy_inv(json_data: ServiceInstall, installed_service: str) -> o stats_password = sql.get_setting('haproxy_stats_password') haproxy_dir = sql.get_setting('haproxy_dir') container_name = sql.get_setting('haproxy_container_name') - haproxy_ver = '2.9.6-1' + haproxy_ver = '3.1.0-1' is_docker = json_data['services']['haproxy']['docker'] for v in json_data['servers']: diff --git a/app/routes/add/routes.py b/app/routes/add/routes.py index 4b0a5b88..51dccdcf 100644 --- a/app/routes/add/routes.py +++ b/app/routes/add/routes.py @@ -18,6 +18,7 @@ import app.modules.roxywi.common as roxywi_common import app.modules.roxy_wi_tools as roxy_wi_tools from app.views.service.haproxy_section_views import (GlobalSectionView, DefaultsSectionView, ListenSectionView, UserListSectionView, PeersSectionView) +from app.views.service.haproxy_lists_views import HaproxyListView from app.modules.roxywi.class_models import DomainName get_config = roxy_wi_tools.GetConfigVar() @@ -38,6 +39,8 @@ register_api_id_ip(PeersSectionView, 'haproxy_peers_post_a', '/section/peers', m register_api_id_ip(PeersSectionView, 'haproxy_peers_a', '/section/peers/', methods=['GET', 'PUT', 'DELETE']) register_api_id_ip(GlobalSectionView, 'haproxy_global_a', '/section/global', methods=['GET', 'PUT']) register_api_id_ip(DefaultsSectionView, 'haproxy_defaults_a', '/section/defaults', methods=['GET', 'PUT']) +bp.add_url_rule('//list//', view_func=HaproxyListView.as_view('list_get'), methods=['GET']) +bp.add_url_rule('//list', view_func=HaproxyListView.as_view('list_post'), methods=['POST', 'DELETE']) @bp.before_request @@ -101,47 +104,6 @@ def get_section_html(): return render_template('ajax/config_show_add_sections.html', lang=lang) -@bp.post('/haproxy/bwlist/create') -@get_user_params() -def create_bwlist(): - server_ip = common.is_ip_or_dns(request.form.get('serv')) - color = common.checkAjaxInput(request.form.get('color')) - group = g.user_params['group_id'] - list_name = common.checkAjaxInput(request.form.get('bwlists_create')) - - return add_mod.create_bwlist(server_ip, list_name, color, group) - - -@bp.post('/haproxy/bwlist/save') -@get_user_params() -def save_bwlist(): - server_ip = common.is_ip_or_dns(request.form.get('serv')) - color = common.checkAjaxInput(request.form.get('color')) - group = g.user_params['group_id'] - bwlists_save = common.checkAjaxInput(request.form.get('bwlists_save')) - list_con = request.form.get('bwlists_content') - action = common.checkAjaxInput(request.form.get('bwlists_restart')) - - return add_mod.save_bwlist(bwlists_save, list_con, color, group, server_ip, action) - - -@bp.route('/haproxy/bwlist/delete////') -@validate() -def delete_bwlist(server_ip: Union[IPvAnyAddress, DomainName], color, name, group): - color = common.checkAjaxInput(color) - list_name = common.checkAjaxInput(name) - - return add_mod.delete_bwlist(list_name, color, group, str(server_ip)) - - -@bp.route('/haproxy/bwlist///') -def get_bwlist(bwlists, color, group): - color = common.checkAjaxInput(color) - bwlists = common.checkAjaxInput(bwlists) - - return add_mod.get_bwlist(color, group, bwlists) - - @bp.route('/haproxy/bwlists//') def get_bwlists(color, group): color = common.checkAjaxInput(color) diff --git a/app/routes/main/routes.py b/app/routes/main/routes.py index 40287546..fd81056e 100644 --- a/app/routes/main/routes.py +++ b/app/routes/main/routes.py @@ -199,7 +199,7 @@ def nettools_check(check, body: NettoolsRequest): @jwt_required() @get_user_params() @validate() -def service_history(service: str, server_ip: Union[IPvAnyAddress, DomainName]): +def service_history(service: str, server_ip: Union[IPvAnyAddress, DomainName, int]): history = '' server_ip = str(server_ip) @@ -217,7 +217,7 @@ def service_history(service: str, server_ip: Union[IPvAnyAddress, DomainName]): server_id = server_sql.get_server_by_ip(server_ip).server_id history = history_sql.select_action_history_by_server_id(server_id) elif service == 'user': - history = history_sql.select_action_history_by_user_id(server_ip) + history = history_sql.select_action_history_by_user_id(int(server_ip)) else: abort(404, 'History not found') diff --git a/app/static/css/dark.css b/app/static/css/dark.css new file mode 100644 index 00000000..5d845300 --- /dev/null +++ b/app/static/css/dark.css @@ -0,0 +1,85 @@ +body, .container, .footer { + background-color: #171717 !important; + color: #F0F0F0 !important; +} +h2 { + color: #F0F0F0; +} +h3 { + background: #b2b2b2; + color: #F0F0F0; +} +.menu a, .v_menu a, .top-menu { + background-color: #1b1b1b !important; + color: #f0f0f0 !important; +} +.menu a:hover { + background: #1f1f1f !important; + color: #f0f0f0 !important; + border-left: none; +} +.overview-wi .overviewHead, .overviewHead { + background-color: #686868 !important; +} +.odd { + background-color: #171717 !important; +} +.even { + background-color: #1f1f1f !important; +} +.menu a { + background-color: #1b1b1b !important; + color: #f0f0f0 !important; +} +.addName { + background-color: #171717; +} +.addButton:hover { + background-color: #171717 !important; +} +.alert-info { + color: #f0f0f0 !important; +} +.form-login { + background-color: #1b1b1b !important; +} +#enter { + color: #F0F0F0; + background-color: #171717 !important; +} +.ui-widget-header { + background-color: #797878 !important; +} +.ui-tabs .ui-tabs-panel { + background-color: #171717 !important; +} +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { + color: #F0F0EF; +} +.ui-dialog .ui-dialog-title { + color: #f0f0f0; +} +.ui-dialog .ui-dialog-content, .ui-widget-content { + background-color: #1f1f1f !important; +} +.ui-widget-header { + border: 1px solid #1f1f1f; +} +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited, a.ui-button, a:link.ui-button, a:visited.ui-button, .ui-button { + color: #f0f0f0; +} +.ui-state-active { + background-color: #797878 !important; + border: none; +} +.ui-widget-content { + color: #f0f0f0 !important; +} +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default, .ui-button, html .ui-button.ui-state-disabled:hover, html .ui-button.ui-state-disabled:active { + border: 1px solid #797878 !important; + background: #1f1f1f !important; + color: #f0f0f0 !important; +} +.ui-menu, .ui-menu-item { + background: #797878 !important; +} \ No newline at end of file diff --git a/app/static/css/styles.css b/app/static/css/styles.css index d9a8e917..d59b9ad2 100644 --- a/app/static/css/styles.css +++ b/app/static/css/styles.css @@ -571,7 +571,7 @@ ul{ border-bottom: 1px solid var(--color-secondary); } .form-login { - background-color: var(--color-gray) !important; + background-color: var(--color-gray); padding: 10px 10px 10px 30px; width: 220px; background-size: 0 !important; @@ -1379,3 +1379,12 @@ label { background-color: #f5f5f5; border: 1px solid #ccc; } +#enter { + width: 220px; + padding: 10px; + background-color: var(--background); + font-weight: bold; + color: var(--color-wanring); + border: 1px solid var(--color-wanring); + border-radius: var(--border-radius); +} diff --git a/app/static/images/HAProxy_icon_white.png b/app/static/images/HAProxy_icon_white.png new file mode 100644 index 00000000..227cdec2 Binary files /dev/null and b/app/static/images/HAProxy_icon_white.png differ diff --git a/app/static/images/NGINX_icon_white.png b/app/static/images/NGINX_icon_white.png new file mode 100644 index 00000000..6cf56572 Binary files /dev/null and b/app/static/images/NGINX_icon_white.png differ diff --git a/app/static/images/keepalived_icon_white.png b/app/static/images/keepalived_icon_white.png new file mode 100644 index 00000000..062755ba Binary files /dev/null and b/app/static/images/keepalived_icon_white.png differ diff --git a/app/static/images/logo_menu_white.png b/app/static/images/logo_menu_white.png new file mode 100644 index 00000000..2aa8a420 Binary files /dev/null and b/app/static/images/logo_menu_white.png differ diff --git a/app/static/images/logo_white.png b/app/static/images/logo_white.png new file mode 100644 index 00000000..8b9080ad Binary files /dev/null and b/app/static/images/logo_white.png differ diff --git a/app/static/images/roxy_icon_white.png b/app/static/images/roxy_icon_white.png new file mode 100644 index 00000000..693420ad Binary files /dev/null and b/app/static/images/roxy_icon_white.png differ diff --git a/app/static/js/add.js b/app/static/js/add.js index ca4ec044..6eec8932 100644 --- a/app/static/js/add.js +++ b/app/static/js/add.js @@ -839,7 +839,7 @@ function resetProxySettings() { $('.advance-show').fadeIn(); $('.advance').fadeOut(); $('[id^=https-hide]').hide(); - $('[name=mode').val('http'); + $('[name=mode]').val('http'); $('select').selectmenu('refresh'); $("#path-cert-listen" ).attr('required',false); $("#path-cert-frontend" ).attr('required',false); @@ -1124,26 +1124,23 @@ function change_select_waf(id) { }); } function createList(color) { - if(color == 'white') { + let list = $('#new_blacklist_name').val() + if (color === 'white') { list = $('#new_whitelist_name').val() - } else { - list = $('#new_blacklist_name').val() } - list = escapeHtml(list); - $.ajax( { - url: "/add/haproxy/bwlist/create", - data: { - bwlists_create: list, - color: color - }, + let jsonData = { + 'name': escapeHtml(list), + 'color': color + } + $.ajax({ + url: "/add/haproxy/list", + data: JSON.stringify(jsonData), type: "POST", - success: function( data ) { - if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1' || data.indexOf('Errno') != '-1') { - toastr.error(data); - } else if (data.indexOf('Info') != '-1' ){ - toastr.clear(); - toastr.info(data); - } else if (data.indexOf('success') != '-1' ) { + contentType: "application/json; charset=utf-8", + success: function (data) { + if (data.status === 'failed') { + toastr.error(data.error); + } else { toastr.clear(); toastr.success('List has been created'); setTimeout(function () { @@ -1151,16 +1148,17 @@ function createList(color) { }, 2500); } } - } ); + }); } function editList(list, color) { $.ajax( { - url: "/add/haproxy/bwlist/" + list + "/" + color + "/" + $('#group_id').val(), + url: "/add/haproxy/list/" + list + "/" + color, + contentType: "application/json; charset=utf-8", success: function( data ) { - if (data.indexOf('error:') != '-1') { - toastr.error(data); + if (data.status === 'failed') { + toastr.error(data.error); } else { - $('#edit_lists').text(data); + $('#edit_lists').text(data.data.replaceAll('\n', '\r\n')); $( "#dialog-confirm-cert-edit" ).dialog({ resizable: false, height: "auto", @@ -1205,25 +1203,31 @@ function editList(list, color) { function saveList(action, list, color) { let serv = $("#serv-" + color + "-list option:selected").val(); if (!checkIsServerFiled($("#serv-" + color + "-list"))) return false; + let jsonData = { + name: list, + server_ip: serv, + content: $('#edit_lists').val(), + color: color, + action: action + } $.ajax({ - url: "/add/haproxy/bwlist/save", - data: { - bwlists_save: list, - serv: serv, - bwlists_content: $('#edit_lists').val(), - color: color, - bwlists_restart: action - }, + url: "/add/haproxy/list", + data: JSON.stringify(jsonData), type: "POST", + contentType: "application/json; charset=utf-8", success: function (data) { - data = data.split(" , "); - for (i = 0; i < data.length; i++) { - if (data[i]) { - if (data[i].indexOf('error: ') != '-1' || data[i].indexOf('Errno') != '-1') { - toastr.error(data[i]); - } else { - if (data[i] != '\n') { - toastr.success(data[i]); + if (data.status === 'failed') { + toastr.error(data.error) + } else { + data = data.data.split(" , "); + for (i = 0; i < data.length; i++) { + if (data[i]) { + if (data[i].indexOf('error: ') != '-1' || data[i].indexOf('Errno') != '-1') { + toastr.error(data[i]); + } else { + if (data[i] != '\n') { + toastr.success(data[i]); + } } } } @@ -1234,24 +1238,39 @@ function saveList(action, list, color) { function deleteList(list, color) { let serv = $( "#serv-"+color+"-list option:selected" ).val(); if(!checkIsServerFiled($("#serv-"+color+"-list"))) return false; + let jsonData = { + 'name': list, + 'color': color, + 'server_ip': serv + } $.ajax({ - url: "/add/haproxy/bwlist/delete/" + serv + "/" + color + "/" + list + "/" + $('#group_id').val(), - success: function (data) { - if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1' || data.indexOf('Errno') != '-1') { - toastr.error(data); - } else if (data.indexOf('Info') != '-1' ){ - toastr.clear(); - toastr.info(data); - } else if (data.indexOf('success') != '-1' ) { + url: "/add/haproxy/list", + type: "DELETE", + data: JSON.stringify(jsonData), + contentType: "application/json; charset=utf-8", + statusCode: { + 204: function (xhr) { toastr.clear(); toastr.success('List has been deleted'); setTimeout(function () {location.reload();}, 2500); + }, + 404: function (xhr) { + toastr.clear(); + toastr.success('List has been deleted'); + setTimeout(function () {location.reload();}, 2500); + } + }, + success: function (data) { + if (data) { + if (data.status === 'failed') { + toastr.error(data); + } } } }); } function createMap() { - map_name = $('#new_map_name').val() + let map_name = $('#new_map_name').val() map_name = escapeHtml(map_name); $.ajax( { url: "/add/map", diff --git a/app/static/js/overview.js b/app/static/js/overview.js index 2074776d..a5237d13 100644 --- a/app/static/js/overview.js +++ b/app/static/js/overview.js @@ -298,11 +298,7 @@ function change_pos(pos, id) { } function showBytes(serv) { $.ajax( { - url: "/service/haproxy/bytes", - data: { - showBytes: serv - }, - type: "POST", + url: "/service/haproxy/bytes/" + serv, beforeSend: function() { $("#show_bin_bout").html(''); $("#sessions").html(''); @@ -320,11 +316,7 @@ function showBytes(serv) { } function showNginxConnections(serv) { $.ajax( { - url: "/service/nginx/connections", - data: { - nginxConnections: serv - }, - type: "POST", + url: "/service/nginx/connections/" + serv, beforeSend: function() { $("#sessions").html(''); }, @@ -341,11 +333,7 @@ function showNginxConnections(serv) { } function showApachekBytes(serv) { $.ajax( { - url: "/service/apache/bytes", - data: { - apachekBytes: serv - }, - type: "POST", + url: "/service/apache/bytes/" + serv, beforeSend: function() { $("#sessions").html(''); }, @@ -362,11 +350,7 @@ function showApachekBytes(serv) { } function keepalivedBecameMaster(serv) { $.ajax( { - url: "/service/keepalived/become-master", - data: { - keepalivedBecameMaster: serv - }, - type: "POST", + url: "/service/keepalived/become-master/" + serv, beforeSend: function() { $("#bin_bout").html(''); }, diff --git a/app/static/js/script.js b/app/static/js/script.js index be320f8e..722069d7 100644 --- a/app/static/js/script.js +++ b/app/static/js/script.js @@ -29,6 +29,11 @@ function escapeHtml(unsafe) { var wait_mess_word = translate_div.attr('data-wait_mess'); var wait_mess = '
'+wait_mess_word+'
' function show_current_page(id) { + let theme = localStorage.getItem('theme'); + let correct_color = 'var(--color-gray-dark-alpha)'; + if (theme === 'dark') { + correct_color = '#181818'; + } id.parent().css('display', 'contents'); id.parent().css('font-size', '13px'); id.parent().css('top', '0'); @@ -36,7 +41,7 @@ function show_current_page(id) { id.parent().children().css('margin-left', '-20px'); id.parent().find('a').css('padding-left', '20px'); id.find('a').css('border-left', '4px solid var(--color-wanring) !important'); - id.find('a').css('background-color', 'var(--color-gray-dark-alpha) !important'); + id.find('a').css('background-color', correct_color +' !important'); } $( function() { $('.menu li ul li').each(function () { @@ -244,9 +249,9 @@ function clearAllAjaxFields() { function showMap() { clearAllAjaxFields(); $('#ajax-config_file_name').empty(); - $.ajax( { + $.ajax({ url: "/config/map/haproxy/" + $("#serv").val() + '/show', - success: function( data ) { + success: function (data) { if (data.indexOf('error:') != '-1') { toastr.error(data); } else { @@ -255,17 +260,17 @@ function showMap() { window.history.pushState("Show Map", "Show Map", '/config/map/' + $("#service").val() + '/' + $("#serv").val()); } } - } ); + }); } function showCompare() { - $.ajax( { + $.ajax({ url: "/config/compare/" + $("#service").val() + "/" + $("#serv").val() + "/show", data: { left: $('#left').val(), right: $("#right").val(), }, type: "POST", - success: function( data ) { + success: function (data) { if (data.indexOf('error:') != '-1') { toastr.error(data); } else { @@ -273,15 +278,15 @@ function showCompare() { $("#ajax").html(data); } } - } ); + }); } function showCompareConfigs() { clearAllAjaxFields(); $('#ajax-config_file_name').empty(); - $.ajax( { + $.ajax({ url: "/config/compare/" + $("#service").val() + "/" + $("#serv").val() + "/files", type: "GET", - success: function( data ) { + success: function (data) { if (data.indexOf('error:') != '-1') { toastr.error(data); } else { @@ -292,7 +297,7 @@ function showCompareConfigs() { window.history.pushState("Show compare config", "Show compare config", '/config/compare/' + $("#service").val() + '/' + $("#serv").val()); } } - } ); + }); } function showConfig() { let service = $('#service').val(); @@ -315,12 +320,12 @@ function showConfig() { "service": service, "config_file_name": config_file_name } - $.ajax( { + $.ajax({ url: "/config/" + service + "/show", data: JSON.stringify(json_data), type: "POST", contentType: "application/json; charset=utf-8", - success: function( data ) { + success: function (data) { if (data.status === 'failed') { toastr.error(data); } else { @@ -330,7 +335,7 @@ function showConfig() { window.history.pushState("Show config", "Show config", "/config/" + service + "/" + $("#serv").val() + "/show/" + config_file_name); } } - } ); + }); } function showConfigFiles(not_redirect=false) { var service = $('#service').val(); @@ -477,6 +482,7 @@ function viewLogs() { } } $( function() { + checkTheme(); $('a').click(function(e) { try { var cur_path = window.location.pathname; @@ -788,11 +794,29 @@ function saveUserSettings(user_id){ localStorage.setItem('disabled_alert', '1'); } changeCurrentGroupF(user_id); + changeTheme($('#theme_select').val()); Cookies.set('lang', $('#lang_select').val(), { expires: 365, path: '/', secure: 'true' }); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } +function changeTheme(theme) { + localStorage.setItem('theme', theme); + if (theme === 'dark') { + $('#menu-overview').children().attr('src', '/static/images/roxy_icon_white.png'); + $('#menu-haproxy').children().attr('src', '/static/images/HAProxy_icon_white.png'); + $('#menu-nginx').children().attr('src', '/static/images/NGINX_icon_white.png'); + $('#menu-keepalived').children().attr('src', '/static/images/keepalived_icon_white.png'); + $('.menu-logo').attr('src', '/static/images/logo_menu_white.png'); + $('head').append(''); + } else { + $('link[rel=stylesheet][href~="/static/css/dark.css"]').remove(); + } +} +function checkTheme() { + let theme = localStorage.getItem('theme'); + changeTheme(theme); +} function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; } @@ -1296,6 +1320,12 @@ function openUserSettings(user_id) { } else { $('#disable_alerting').prop('checked', true).checkboxradio('refresh'); } + let theme = 'light'; + if (localStorage.getItem('theme') != null) { + theme = localStorage.getItem('theme'); + } + $('#theme_select').val(theme).change(); + $('#theme_select').selectmenu('refresh'); $.ajax({ url: "/user/group", success: function (data) { diff --git a/app/templates/base.html b/app/templates/base.html index a9b09432..b59f573b 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -66,11 +66,6 @@
-{# #}