diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/ServiceController.php b/src/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/ServiceController.php index 5f3a13abb..c53ebc73b 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/ServiceController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/ServiceController.php @@ -79,12 +79,19 @@ class ServiceController extends ApiControllerBase public function statusAction() { $backend = new Backend(); + $mdlProxy = new Proxy(); $response = $backend->configdRun("proxy status"); if (strpos($response, "not running") > 0) { - $status = "stopped"; + if ($mdlProxy->general->enabled->__toString() == 1) { + $status = "stopped"; + } else { + $status = "disabled"; + } } elseif (strpos($response, "is running") > 0) { $status = "running"; + } elseif ($mdlProxy->general->enabled->__toString() == 0) { + $status = "disabled"; } else { $status = "unkown"; } diff --git a/src/opnsense/mvc/app/views/OPNsense/Proxy/index.volt b/src/opnsense/mvc/app/views/OPNsense/Proxy/index.volt index 4994f802a..f461b18b7 100644 --- a/src/opnsense/mvc/app/views/OPNsense/Proxy/index.volt +++ b/src/opnsense/mvc/app/views/OPNsense/Proxy/index.volt @@ -30,23 +30,21 @@ POSSIBILITY OF SUCH DAMAGE. $( document ).ready(function() { - data_get_map = {'frm_proxy':"/api/proxy/settings/get"}; + var data_get_map = {'frm_proxy':"/api/proxy/settings/get"}; + + // load initial data - $.each(data_get_map, function(data_index, data_url) { - ajaxGet(url=data_url,sendData={},callback=function(data,status) { - if (status == "success") { - $("form").each(function( index ) { - if ( $(this).attr('id').split('-')[0] == data_index) { - // related form found, load data - setFormData($(this).attr('id'),data); - } - }); - } + mapDataToFormUI(data_get_map).done(function(){ + formatTokenizersUI(); + $('.selectpicker').selectpicker('refresh'); + // request service status on load and update status box + ajaxCall(url="/api/proxy/service/status", sendData={}, callback=function(data,status) { + updateServiceStatusUI("proxy",data['responseText']); }); }); - // form event handlers + // form save event handlers for all defined forms $('[id*="save_"]').each(function(){ $(this).click(function() { var frm_id = $(this).closest("form").attr("id"); @@ -69,100 +67,18 @@ POSSIBILITY OF SUCH DAMAGE. message: JSON.stringify(data), draggable: true }); + } else { + // request service status after successful save and update status box + ajaxCall(url="/api/proxy/service/status", sendData={}, callback=function(data,status) { + updateServiceStatusUI("proxy",data['responseText']); + }); } }); - }); }); }); - // handle help messages show/hide - $('[id*="show_all_help"]').click(function() { - $('[id*="show_all_help"]').toggleClass("fa-toggle-on fa-toggle-off"); - $('[id*="show_all_help"]').toggleClass("text-success text-danger"); - if ($('[id*="show_all_help"]').hasClass("fa-toggle-on")) { - $('[for*="help_for"]').addClass("show"); - $('[for*="help_for"]').removeClass("hidden"); - } else { - $('[for*="help_for"]').addClass("hidden"); - $('[for*="help_for"]').removeClass("show"); - } - }); - - // handle advanced show/hide - $('[data-advanced*="true"]').hide(function(){ - $('[data-advanced*="true"]').after(""); // the table row is added to keep correct table striping - }); - $('[id*="show_advanced"]').click(function() { - $('[id*="show_advanced"]').toggleClass("fa-toggle-on fa-toggle-off"); - $('[id*="show_advanced"]').toggleClass("text-success text-danger"); - if ($('[id*="show_advanced"]').hasClass("fa-toggle-on")) { - $('[data-advanced*="true"]').show(); - $('[data-advanced*="hidden_row"]').remove(); // the table row is deleted to keep correct table striping - } else { - $('[data-advanced*="true"]').after("").hide(); // the table row is added to keep correct table striping - } - }); - - // Apply tokenizer - setTimeout(function(){ - $('select[class="tokenize"]').each(function(){ - if ($(this).prop("size")==0) { - maxDropdownHeight=String(36*5)+"px"; // default number of items - - } else { - number_of_items = $(this).prop("size"); - maxDropdownHeight=String(36*number_of_items)+"px"; - } - hint=$(this).data("hint"); - width=$(this).data("width"); - allownew=$(this).data("allownew"); - maxTokenContainerHeight=$(this).data("maxheight"); - - $(this).tokenize({ - displayDropdownOnFocus: true, - newElements: allownew, - placeholder:hint - }); - $(this).parent().find('ul[class="TokensContainer"]').parent().css("width",width); - $(this).parent().find('ul[class="Dropdown"]').css("max-height", maxDropdownHeight); - if ( maxDropdownHeight != undefined ) { - $(this).parent().find('ul[class="TokensContainer"]').css("max-height", maxTokenContainerHeight); - } - }); - // TODO: fix loading order - $('.selectpicker').selectpicker('refresh'); - },500); - - // clear multiselect boxes, works on standard and tokenized versions - $('[id*="clear-options"]').each(function() { - $(this).click(function() { - var id = $(this).attr("for"); - BootstrapDialog.confirm({ - title: 'Deselect or remove all items ?', - message: 'Deselect or remove all items ?', - type: BootstrapDialog.TYPE_DANGER, - closable: true, - draggable: true, - btnCancelLabel: 'Cancel', - btnOKLabel: 'Yes', - btnOKClass: 'btn-primary', - callback: function(result) { - if(result) { - if ($('select[id="' + id + '"]').hasClass("tokenize")) { - // trigger close on all Tokens - $('select[id="' + id + '"]').parent().find('ul[class="TokensContainer"]').find('li[class="Token"]').find('a').trigger("click"); - } else { - // remove options from selection - $('select[id="' + id + '"]').find('option').prop('selected',false); - } - } - } - }); - }); - }); - }); diff --git a/src/opnsense/mvc/app/views/layouts/default.volt b/src/opnsense/mvc/app/views/layouts/default.volt index db26f4f17..30eced9dd 100644 --- a/src/opnsense/mvc/app/views/layouts/default.volt +++ b/src/opnsense/mvc/app/views/layouts/default.volt @@ -40,21 +40,21 @@ } }); - // handle help messages show/hide - $("a[class='showhelp']").click(function () { - $("*[for='" + $(this).attr('id') + "']").toggleClass("hidden show"); - }); - // hide empty menu items $('#mainmenu > div > .collapse').each(function(){ if ($(this).children().length == 0) { $("#mainmenu").find('[href="#'+$(this).attr('id')+'"]').remove(); } }); - }); + initFormHelpUI(); + initFormAdvancedUI(); + addMultiSelectClearUI(); + + }); + @@ -112,8 +112,8 @@ @@ -147,6 +147,5 @@ - - + diff --git a/src/opnsense/www/js/opnsense.js b/src/opnsense/www/js/opnsense.js index db7c22075..2c0498a25 100644 --- a/src/opnsense/www/js/opnsense.js +++ b/src/opnsense/www/js/opnsense.js @@ -1,4 +1,37 @@ /** + * Copyright (C) 2015 Deciso B.V. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * shared components + * + */ + + /** + * * Map input fields from given parent tag to structure of named arrays. * * @param parent tag id in dom @@ -6,14 +39,14 @@ */ function getFormData(parent) { - data = {}; + var data = {}; $( "#"+parent+" input,#"+parent+" select" ).each(function( index ) { if ($(this).prop('id') == undefined) { // we need an id. return; } - node = data ; - keyparts = $(this).prop('id').split('.'); + var node = data ; + var keyparts = $(this).prop('id').split('.'); for (var i in keyparts) { if (!(keyparts[i] in node)) { node[keyparts[i]] = {}; @@ -67,8 +100,8 @@ function setFormData(parent,data) { // we need an id. return; } - node = data ; - keyparts = $(this).prop('id').split('.'); + var node = data ; + var keyparts = $(this).prop('id').split('.'); for (var i in keyparts) { if (!(keyparts[i] in node)) { break; diff --git a/src/opnsense/www/js/opnsense_ui.js b/src/opnsense/www/js/opnsense_ui.js index 55c53472b..eab71f956 100644 --- a/src/opnsense/www/js/opnsense_ui.js +++ b/src/opnsense/www/js/opnsense_ui.js @@ -1,5 +1,32 @@ /** - * User interface shared components, requires opnsense.js for supporting functions. + * Copyright (C) 2015 Deciso B.V. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * User interface shared components, requires opnsense.js for supporting functions. */ /** @@ -8,7 +35,7 @@ * @param formid parent id to grep input data from */ function saveFormToEndpoint(url,formid,callback_ok) { - data = getFormData(formid); + var data = getFormData(formid); ajaxCall(url=url,sendData=data,callback=function(data,status){ if ( status == "success") { // update field validation @@ -38,5 +65,163 @@ function saveFormToEndpoint(url,formid,callback_ok) { } }); - +} + +/** + * standard data mapper to map json request data to forms on this page + * @param data_get_map named array containing form names and source url's to get data from {'frm_example':"/api/example/settings/get"}; + * @return promise object, resolves when all are loaded + */ +function mapDataToFormUI(data_get_map) { + var dfObj = new $.Deferred(); + + // calculate number of items for deferred object to resolve + var data_map_seq = 1; + var data_map_count = 0; + $.each(data_get_map, function(){ + data_map_count += 1; + }); + + $.each(data_get_map, function(data_index, data_url) { + ajaxGet(url=data_url,sendData={}, callback=function(data, status) { + if (status == "success") { + $("form").each(function( index ) { + if ( $(this).attr('id').split('-')[0] == data_index) { + // related form found, load data + setFormData($(this).attr('id'), data); + } + }); + } + if (data_map_seq == data_map_count) { + dfObj.resolve(data_map_seq); + } + data_map_seq += 1; + }); + }); + + return dfObj; +} + +/** + * update service status buttons in user interface + */ +function updateServiceStatusUI(service, status) { + + var status_html = ''; + + if (status == "running") { + status_html += '' ; + } else if (status == "stopped") { + status_html += '' ; + } else { + status_html += '' ; + } + + status_html += '  '; + + $('#service_status_container').html(status_html); +} + +/** + * reformat all tokenizers on this document + */ +function formatTokenizersUI(){ + $('select[class="tokenize"]').each(function(){ + if ($(this).prop("size")==0) { + maxDropdownHeight=String(36*5)+"px"; // default number of items + + } else { + number_of_items = $(this).prop("size"); + maxDropdownHeight=String(36*number_of_items)+"px"; + } + hint=$(this).data("hint"); + width=$(this).data("width"); + allownew=$(this).data("allownew"); + maxTokenContainerHeight=$(this).data("maxheight"); + + $(this).tokenize({ + displayDropdownOnFocus: true, + newElements: allownew, + placeholder:hint + }); + $(this).parent().find('ul[class="TokensContainer"]').parent().css("width",width); + $(this).parent().find('ul[class="Dropdown"]').css("max-height", maxDropdownHeight); + if ( maxDropdownHeight != undefined ) { + $(this).parent().find('ul[class="TokensContainer"]').css("max-height", maxTokenContainerHeight); + } + }); +} + +/** + * clear multiselect boxes on click event, works on standard and tokenized versions + */ +function addMultiSelectClearUI() { + $('[id*="clear-options"]').each(function() { + $(this).click(function() { + var id = $(this).attr("for"); + BootstrapDialog.confirm({ + title: 'Deselect or remove all items ?', + message: 'Deselect or remove all items ?', + type: BootstrapDialog.TYPE_DANGER, + closable: true, + draggable: true, + btnCancelLabel: 'Cancel', + btnOKLabel: 'Yes', + btnOKClass: 'btn-primary', + callback: function(result) { + if(result) { + if ($('select[id="' + id + '"]').hasClass("tokenize")) { + // trigger close on all Tokens + $('select[id="' + id + '"]').parent().find('ul[class="TokensContainer"]').find('li[class="Token"]').find('a').trigger("click"); + } else { + // remove options from selection + $('select[id="' + id + '"]').find('option').prop('selected',false); + } + } + } + }); + }); + }); +} + +/** + * setup form help buttons + */ +function initFormHelpUI() { + // handle help messages show/hide + $("a[class='showhelp']").click(function () { + $("*[for='" + $(this).attr('id') + "']").toggleClass("hidden show"); + }); + + // handle all help messages show/hide + $('[id*="show_all_help"]').click(function() { + $('[id*="show_all_help"]').toggleClass("fa-toggle-on fa-toggle-off"); + $('[id*="show_all_help"]').toggleClass("text-success text-danger"); + if ($('[id*="show_all_help"]').hasClass("fa-toggle-on")) { + $('[for*="help_for"]').addClass("show"); + $('[for*="help_for"]').removeClass("hidden"); + } else { + $('[for*="help_for"]').addClass("hidden"); + $('[for*="help_for"]').removeClass("show"); + } + }); +} + +/** + * handle advanced show/hide + */ +function initFormAdvancedUI() { + $('[data-advanced*="true"]').hide(function(){ + $('[data-advanced*="true"]').after(""); // the table row is added to keep correct table striping + }); + $('[id*="show_advanced"]').click(function() { + $('[id*="show_advanced"]').toggleClass("fa-toggle-on fa-toggle-off"); + $('[id*="show_advanced"]').toggleClass("text-success text-danger"); + if ($('[id*="show_advanced"]').hasClass("fa-toggle-on")) { + $('[data-advanced*="true"]').show(); + $('[data-advanced*="hidden_row"]').remove(); // the table row is deleted to keep correct table striping + } else { + $('[data-advanced*="true"]').after("").hide(); // the table row is added to keep correct table striping + } + }); }