%PDF- %PDF-
Direktori : /backups/router/usr/local/opnsense/mvc/app/views/layouts/ |
Current File : //backups/router/usr/local/opnsense/mvc/app/views/layouts/default.volt |
<!doctype html> <html lang="{{ langcode|safe }}" class="no-js"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="robots" content="noindex, nofollow" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <meta name="copyright" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes"> <title>{{headTitle|default("OPNsense") }} | {{system_hostname}}.{{system_domain}}</title> {% set theme_name = ui_theme|default('opnsense') %} <!-- Favicon --> <link href="{{ cache_safe('/ui/themes/%s/build/images/favicon.png' | format(theme_name)) }}" rel="shortcut icon"> <!-- css imports --> {% for filename in css_files -%} <link href="{{ cache_safe(theme_file_or_default(filename, theme_name)) }}" rel="stylesheet"> {% endfor %} <!-- TODO: move to theme style --> <style> .menu-level-3-item { font-size: 90%; padding-left: 54px !important; } .typeahead { overflow: hidden; } </style> <!-- script imports --> {% for filename in javascript_files -%} <script src="{{ cache_safe(filename) }}"></script> {% endfor %} <script> // setup default scripting after page loading. $( document ).ready(function() { // hook into jquery ajax requests to ensure csrf handling. $.ajaxSetup({ 'beforeSend': function(xhr) { xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}" ); } }); // propagate ajax error messages $( document ).ajaxError(function( event, request ) { if (request.responseJSON != undefined && request.responseJSON.errorMessage != undefined) { BootstrapDialog.show({ type: BootstrapDialog.TYPE_DANGER, title: request.responseJSON.errorTitle, message:request.responseJSON.errorMessage, buttons: [{ label: '{{ lang._('Close') }}', action: function(dialogItself){ dialogItself.close(); } }] }); } }); // hide empty menu items $('#mainmenu > div > .collapse').each(function () { // cleanup empty second level menu containers $(this).find("div.collapse").each(function () { if ($(this).children().length == 0) { $("#mainmenu").find('[href="#' + $(this).attr('id') + '"]').remove(); $(this).remove(); } }); // cleanup empty first level menu items if ($(this).children().length == 0) { $("#mainmenu").find('[href="#' + $(this).attr('id') + '"]').remove(); } }); // hide submenu items $('#mainmenu .list-group-item').click(function(){ if($(this).attr('href').substring(0,1) == '#') { $('#mainmenu .list-group-item').each(function(){ if ($(this).attr('aria-expanded') == 'true' && $(this).data('parent') != '#mainmenu') { $("#"+$(this).attr('href').substring(1,999)).collapse('hide'); } }); } }); initFormHelpUI(); initFormAdvancedUI(); addMultiSelectClearUI(); updateSystemStatus(); // Register collapsible table headers $('.table').on('click', 'thead', function(event) { let collapse = $(event.currentTarget).next(); let id = collapse.attr('class'); if (collapse != undefined && id !== undefined && id === "collapsible") { let icon = $('> tr > th > div > i', event.currentTarget); if (collapse.is(':hidden')) { collapse.toggle(0); collapse.css('display', ''); icon.toggleClass("fa-angle-right fa-angle-down"); return; } icon.toggleClass("fa-angle-down fa-angle-right"); $('> tr > td', collapse).toggle(0); } }); // hook in live menu search $.ajax("/api/core/menu/search/", { type: 'get', cache: false, dataType: "json", data: {}, error : function (jqXHR, textStatus, errorThrown) { console.log('menu.search : ' +errorThrown); }, success: function (data) { var menusearch_items = []; $.each(data,function(idx, menu_item){ if (menu_item.Url != "") { menusearch_items.push({id:$('<div />').html(menu_item.Url).text(), name:menu_item.breadcrumb}); } }); $("#menu_search_box").typeahead({ source: menusearch_items, matcher: function (item) { var ar = this.query.trim(); if (ar == "") { return false; } ar = ar.toLowerCase().split(/\s+/); if (ar.length == 0) { return false; } var it = this.displayText(item).toLowerCase(); for (var i = 0; i < ar.length; i++) { if (it.indexOf(ar[i]) == -1) { return false; } } return true; }, afterSelect: function(item){ // (re)load page if (window.location.href.split("#")[0].indexOf(item.id.split("#")[0]) > -1 ) { // same url, different hash marker window.location.href = item.id; window.location.reload(); } else { window.location.href = item.id; } } }); } }); // change search input size on focus() to fit results $("#menu_search_box").focus(function(){ $("#menu_search_box").css('width', '450px'); $("#system_status").hide(); }); $("#menu_search_box").focusout(function(){ $("#menu_search_box").css('width', '250px'); $("#system_status").show(); }); // enable bootstrap tooltips $('[data-toggle="tooltip"]').tooltip(); // fix menu scroll position on page load $(".list-group-item.active").each(function(){ var navbar_center = ($( window ).height() - $(".collapse.navbar-collapse").height())/2; $('html,aside').scrollTop(($(this).offset().top - navbar_center)); }); // prevent form submits on mvc pages $("form").submit(function() { return false; }); /* overwrite clipboard paste behavior and trim before paste */ $("input").on('paste', function(e) { let clipboard_data = e.originalEvent.clipboardData.getData("text/plain").trim(); if (clipboard_data.length > 0) { e.preventDefault(); document.execCommand('insertText', false, clipboard_data); } }); }); </script> <!-- theme JS --> <script src="{{ cache_safe(theme_file_or_default('/js/theme.js', theme_name)) }}"></script> </head> <body> <header class="page-head"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="/"> {% if file_exists(["/usr/local/opnsense/www/themes/",theme_name,"/build/images/default-logo.svg"]|join("")) %} <img class="brand-logo" src="{{ cache_safe('/ui/themes/%s/build/images/default-logo.svg' | format(theme_name)) }}" height="30" alt="logo"/> {% else %} <img class="brand-logo" src="{{ cache_safe('/ui/themes/%s/build/images/default-logo.png' | format(theme_name)) }}" height="30" alt="logo"/> {% endif %} {% if file_exists(["/usr/local/opnsense/www/themes/",theme_name,"/build/images/icon-logo.svg"]|join("")) %} <img class="brand-icon" src="{{ cache_safe('/ui/themes/%s/build/images/icon-logo.svg' | format(theme_name)) }}" height="30" alt="icon"/> {% else %} <img class="brand-icon" src="{{ cache_safe('/ui/themes/%s/build/images/icon-logo.png' | format(theme_name)) }}" height="30" alt="icon"/> {% endif %} </a> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navigation"> <span class="sr-only">{{ lang._('Toggle navigation') }}</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <button class="toggle-sidebar" data-toggle="tooltip right" title="{{ lang._('Toggle sidebar') }}" style="display:none;"><i class="fa fa-chevron-left"></i></button> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav navbar-right"> <li id="menu_messages"> <span class="navbar-text">{{session_username}}@{{system_hostname}}.{{system_domain}}</span> </li> <li> <span class="navbar-text" style="margin-left: 0"> <i id="system_status" data-toggle="tooltip left" title="{{ lang._('Show system status') }}" style="cursor:pointer" class="fa fa-circle text-muted"></i> </span> </li> <li> <form class="navbar-form" role="search"> <div class="input-group"> <div class="input-group-addon"><i class="fa fa-search"></i></div> <input type="text" style="width: 250px;" class="form-control" tabindex="1" data-provide="typeahead" id="menu_search_box" autocomplete="off"> </div> </form> </li> </ul> </div> </div> </nav> </header> <main class="page-content col-sm-9 col-sm-push-3 col-lg-10 col-lg-push-2"> <!-- menu system --> {{ partial("layout_partials/base_menu_system") }} <div class="row"> <!-- page header --> <header class="page-content-head"> <div class="container-fluid"> <ul class="list-inline"> <li><h1>{{title | default("")}}</h1></li> <li class="btn-group-container" id="service_status_container"></li> </ul> </div> </header> <!-- page content --> <section class="page-content-main"> <div class="container-fluid"> <div class="row"> <!-- notification banner dynamically inserted here (opnsense_status.js) --> <section class="col-xs-12"> <div id="messageregion"></div> {{ content() }} </section> </div> </div> </section> <!-- page footer --> <footer class="page-foot"> <div class="container-fluid"> <a target="_blank" href="{{ product_website }}">{{ product_name }}</a> (c) {{ product_copyright_years }} <a target="_blank" href="{{ product_copyright_url }}">{{ product_copyright_owner }}</a> </div> </footer> </div> </main> <!-- dialog "wait for (service) action" --> <div class="modal fade" id="OPNsenseStdWaitDialog" tabindex="-1" data-backdrop="static" data-keyboard="false"> <div class="modal-backdrop fade in"></div> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-body"> <p><strong>{{ lang._('Please wait...') }}</strong></p> <div class="progress"> <div class="progress-bar progress-bar-info progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width:100%"></div> </div> </div> </div> </div> </div> <script> /* hook translations when all JS modules are loaded*/ $.extend(jQuery.fn.bootgrid.prototype.constructor.Constructor.defaults.labels, { all: "{{ lang._('All') }}", infos: "{{ lang._('Showing %s to %s of %s entries') | format('{{ctx.start}}','{{ctx.end}}','{{ctx.total}}') }}", loading: "{{ lang._('Loading...') }}", noResults: "{{ lang._('No results found!') }}", refresh: "{{ lang._('Refresh') }}", search: "{{ lang._('Search') }}" }); $.extend(jQuery.fn.selectpicker.Constructor.DEFAULTS, { noneSelectedText: "{{ lang._('Nothing selected') }}", noneResultsText: "{{ lang._('No results matched {0}') }}", selectAllText: "{{ lang._('Select All') }}", deselectAllText: "{{ lang._('Deselect All') }}" }); $.extend(jQuery.fn.UIBootgrid.defaults, { removeWarningText: "{{ lang._('Remove selected item(s)?') }}", editText: "{{ lang._('Edit') }}", cloneText: "{{ lang._('Clone') }}", deleteText: "{{ lang._('Delete') }}", addText: "{{ lang._('Add') }}", infoText: "{{ lang._('Info') }}", enableText: "{{ lang._('Enable') }}", disableText: "{{ lang._('Disable') }}", deleteSelectedText: "{{ lang._('Delete selected') }}" }); $.extend(stdDialogRemoveItem.defaults, { title: "{{ lang._('Remove') }}", accept: "{{ lang._('Yes') }}", decline: "{{ lang._('Cancel') }}" }); </script> </body> </html>