Commit e472f132 authored by Ad Schellevis's avatar Ad Schellevis

proxy UI cleanups and move some functionality into the core MVC template

parent 603e91c2
......@@ -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";
}
......
......@@ -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("<tr data-advanced='hidden_row'></tr>"); // 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("<tr data-advanced='hidden_row'></tr>").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);
}
}
}
});
});
});
});
......
......@@ -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();
});
</script>
<!-- bootstrap dialog -->
<link href="/ui/themes/opnsense/build/css/bootstrap-dialog.css" rel="stylesheet" type="text/css" />
......@@ -112,8 +112,8 @@
<ul class="list-inline">
<li class="__mb"><h1>{{title | default("")}}</h1></li>
<li class="btn-group-container">
<!-- <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal_widgets"><span class="glyphicon glyphicon-plus-sign __iconspacer"></span>Add widget</button> -->
<li class="btn-group-container" id="service_status_container">
<!-- placeholder for service status buttons -->
</li>
</ul>
</div>
......@@ -147,6 +147,5 @@
<script type="text/javascript" src="/ui/js/bootstrap-select.min.js"></script>
<!-- bootstrap dialog -->
<script src="/ui/js/bootstrap-dialog.js"></script>
</body>
</body>
</html>
/**
* 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;
......
/**
* 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 += '<span class="btn btn-success">' ;
} else if (status == "stopped") {
status_html += '<span class="btn btn-danger">' ;
} else {
status_html += '<span class="btn">' ;
}
status_html += '<span class="glyphicon glyphicon-play" data-placement="bottom"></span> </span>&nbsp;';
$('#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("<tr data-advanced='hidden_row'></tr>"); // 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("<tr data-advanced='hidden_row'></tr>").hide(); // the table row is added to keep correct table striping
}
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment