net/frr - style cleanup and unify forms (#4450)

* net/frr - style cleanup and unify forms

Apply frontend / api changes to align more with current core patterns.

* net/frr - change maintainer to core
This commit is contained in:
Ad Schellevis
2025-01-08 09:18:03 +01:00
committed by GitHub
parent 5816a72332
commit fc23b6a700
11 changed files with 367 additions and 548 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ PLUGIN_NAME= frr
PLUGIN_VERSION= 1.42
PLUGIN_COMMENT= The FRRouting Protocol Suite
PLUGIN_DEPENDS= frr8
PLUGIN_MAINTAINER= franz.fabian.94@gmail.com
PLUGIN_MAINTAINER= ad@opnsense.org
PLUGIN_TIER= 2
.include "../../Mk/plugins.mk"
@@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2015-2017 Deciso B.V.
* Copyright (C) 2015-2025 Deciso B.V.
* Copyright (C) 2017 Fabian Franz
* Copyright (C) 2017-2021 Michael Muenz <m.muenz@gmail.com>
* All rights reserved.
@@ -39,17 +39,11 @@ class BfdController extends ApiMutableModelControllerBase
public function searchNeighborAction()
{
return $this->searchBase(
'neighbors.neighbor',
array("enabled",
"description",
"address")
);
return $this->searchBase('neighbors.neighbor');
}
public function getNeighborAction($uuid = null)
{
$this->sessionClose();
return $this->getBase('neighbor', 'neighbors.neighbor', $uuid);
}
@@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2015-2017 Deciso B.V.
* Copyright (C) 2015-2025 Deciso B.V.
* Copyright (C) 2017 Fabian Franz
* All rights reserved.
*
@@ -29,46 +29,10 @@
namespace OPNsense\Quagga\Api;
use OPNsense\Base\ApiControllerBase;
use OPNsense\Quagga\General;
use OPNsense\Core\Config;
use OPNsense\Base\ApiMutableModelControllerBase;
class GeneralController extends ApiControllerBase
class GeneralController extends ApiMutableModelControllerBase
{
public function getAction()
{
// define list of configurable settings
$result = array();
if ($this->request->isGet()) {
$mdlGeneral = new General();
$result['general'] = $mdlGeneral->getNodes();
}
return $result;
}
public function setAction()
{
$result = array("result" => "failed");
if ($this->request->isPost()) {
// load model and update with provided data
$mdlGeneral = new General();
$mdlGeneral->setNodes($this->request->getPost("general"));
// perform validation
$valMsgs = $mdlGeneral->performValidation();
foreach ($valMsgs as $field => $msg) {
if (!array_key_exists("validations", $result)) {
$result["validations"] = array();
}
$result["validations"]["general." . $msg->getField()] = $msg->getMessage();
}
// serialize model to config and save
if ($valMsgs->count() == 0) {
$mdlGeneral->serializeToConfig();
Config::getInstance()->save();
$result["result"] = "saved";
}
}
return $result;
}
protected static $internalModelName = 'general';
protected static $internalModelClass = '\OPNsense\Quagga\General';
}
@@ -1,6 +1,7 @@
<?php
/*
* Copyright (C) 2025 Deciso B.V.
* Copyright (C) 2017 Fabian Franz
* Copyright (C) 2019 Michael Muenz <m.muenz@gmail.com>
* All rights reserved.
@@ -38,38 +39,34 @@ class OspfsettingsController extends ApiMutableModelControllerBase
public function searchNetworkAction()
{
return $this->searchBase('networks.network', array("enabled", "ipaddr", "netmask", "area"));
return $this->searchBase('networks.network');
}
public function searchInterfaceAction()
{
return $this->searchBase('interfaces.interface', array("enabled", "interfacename", "networktype", "authtype", "area"));
return $this->searchBase('interfaces.interface');
}
public function searchPrefixlistAction()
{
return $this->searchBase('prefixlists.prefixlist', array("enabled", "name", "seqnumber", "action", "network" ));
return $this->searchBase('prefixlists.prefixlist');
}
public function searchRoutemapAction()
{
return $this->searchBase('routemaps.routemap', array("enabled", "name", "action", "id", "match2", "set"));
return $this->searchBase('routemaps.routemap');
}
public function getNetworkAction($uuid = null)
{
$this->sessionClose();
return $this->getBase('network', 'networks.network', $uuid);
}
public function getInterfaceAction($uuid = null)
{
$this->sessionClose();
return $this->getBase('interface', 'interfaces.interface', $uuid);
}
public function getPrefixlistAction($uuid = null)
{
$this->sessionClose();
return $this->getBase('prefixlist', 'prefixlists.prefixlist', $uuid);
}
public function getRoutemapAction($uuid = null)
{
$this->sessionClose();
return $this->getBase('routemap', 'routemaps.routemap', $uuid);
}
public function addNetworkAction()
@@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2015-2017 Deciso B.V.
* Copyright (C) 2015-2025 Deciso B.V.
* Copyright (C) 2017 Fabian Franz
* All rights reserved.
*
@@ -29,121 +29,16 @@
namespace OPNsense\Quagga\Api;
use OPNsense\Base\ApiControllerBase;
use OPNsense\Core\Backend;
use OPNsense\Quagga\General;
use OPNsense\Base\ApiMutableServiceControllerBase;
/**
* Class ServiceController
* @package OPNsense\Quagga
*/
class ServiceController extends ApiControllerBase
class ServiceController extends ApiMutableServiceControllerBase
{
/**
* start quagga service and reload filter rules to pass OSPF
* before the bogon filter kills the routing protocol packets
* @return array
*/
public function startAction()
{
if ($this->request->isPost()) {
$backend = new Backend();
$response = $backend->configdRun('quagga start');
$backend->configdRun('filter reload');
return array('response' => $response);
} else {
return array('response' => array());
}
}
/**
* stop quagga service
* @return array
*/
public function stopAction()
{
if ($this->request->isPost()) {
$backend = new Backend();
$response = $backend->configdRun('quagga stop');
return array('response' => $response);
} else {
return array('response' => array());
}
}
/**
* restart quagga service
* @return array
*/
public function restartAction()
{
if ($this->request->isPost()) {
$backend = new Backend();
$response = $backend->configdRun('quagga restart');
$backend->configdRun('filter reload');
return array('response' => $response);
} else {
return array('response' => array());
}
}
/**
* retrieve status of quagga
* @return array
* @throws \Exception
*/
public function statusAction()
{
$backend = new Backend();
$mdlGeneral = new General();
$response = $backend->configdRun('quagga status');
if (strpos($response, 'not running') > 0) {
if ($mdlGeneral->enabled->__toString() == 1) {
$status = 'stopped';
} else {
$status = 'disabled';
}
} elseif (strpos($response, 'is running') > 0) {
$status = 'running';
} elseif ($mdlGeneral->enabled->__toString() == 0) {
$status = 'disabled';
} else {
$status = 'unknown';
}
return array('status' => $status);
}
/**
* reconfigure quagga, generate config and reload
*/
public function reconfigureAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$mdlGeneral = new General();
$backend = new Backend();
$runStatus = $this->statusAction();
// stop quagga if it is running or not
$this->stopAction();
// generate template
$backend->configdRun('template reload OPNsense/Quagga');
// (res)start daemon
if ($mdlGeneral->enabled->__toString() == 1) {
$this->startAction();
}
return array('status' => 'ok');
} else {
return array('status' => 'failed');
}
}
protected static $internalServiceClass = '\OPNsense\Quagga\General';
protected static $internalServiceTemplate = 'OPNsense/Quagga';
protected static $internalServiceEnabled = 'enabled';
protected static $internalServiceName = 'quagga';
}
@@ -1,6 +1,6 @@
{#
OPNsense® is Copyright © 2014 2017 by Deciso B.V.
OPNsense® is Copyright © 2014 2025 by Deciso B.V.
Copyright (C) 2017 Fabian Franz
Copyright (C) 2017 - 2021 Michael Muenz <m.muenz@gmail.com>
All rights reserved.
@@ -27,20 +27,46 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
#}
<script>
$( document ).ready(function() {
mapDataToFormUI({'frm_bfd_settings':"/api/quagga/bfd/get"}).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('quagga');
});
$("#grid-neighbors").UIBootgrid({
'search':'/api/quagga/bfd/searchNeighbor',
'get':'/api/quagga/bfd/getNeighbor/',
'set':'/api/quagga/bfd/setNeighbor/',
'add':'/api/quagga/bfd/addNeighbor/',
'del':'/api/quagga/bfd/delNeighbor/',
'toggle':'/api/quagga/bfd/toggleNeighbor/'
});
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/quagga/bfd/set", 'frm_bfd_settings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status) {
updateServiceControlUI('quagga');
}
});
});
</script>
<!-- Navigation bar -->
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
<li class="active"><a data-toggle="tab" href="#general">{{ lang._('General') }}</a></li>
<li><a data-toggle="tab" href="#neighbors">{{ lang._('Neighbors') }}</a></li>
</ul>
<div class="tab-content content-box tab-content">
<div id="general" class="tab-pane fade in active">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':bfdForm,'id':'frm_bfd_settings'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
{{ partial("layout_partials/base_form",['fields':bfdForm,'id':'frm_bfd_settings'])}}
</div>
<div id="neighbors" class="tab-pane fade in">
<table id="grid-neighbors" class="table table-responsive" data-editDialog="DialogEditBFDNeighbor">
@@ -57,10 +83,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="10"></td>
<td colspan="1">
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -68,51 +94,19 @@ POSSIBILITY OF SUCH DAMAGE.
</div>
</div>
<script>
function quagga_update_status() {
updateServiceControlUI('quagga');
}
$(document).ready(function() {
var data_get_map = {'frm_bfd_settings':"/api/quagga/bfd/get"};
mapDataToFormUI(data_get_map).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
});
quagga_update_status();
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/quagga/bfd/set",formid='frm_bfd_settings',callback_ok=function(){
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
quagga_update_status();
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
});
/* allow a user to manually reload the service (for forms which do not do it automatically) */
$('.reload_btn').click(function reload_handler() {
$(".reloadAct_progress").addClass("fa-spin");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
quagga_update_status();
$(".reloadAct_progress").removeClass("fa-spin");
});
});
$("#grid-neighbors").UIBootgrid(
{ 'search':'/api/quagga/bfd/searchNeighbor',
'get':'/api/quagga/bfd/getNeighbor/',
'set':'/api/quagga/bfd/setNeighbor/',
'add':'/api/quagga/bfd/addNeighbor/',
'del':'/api/quagga/bfd/delNeighbor/',
'toggle':'/api/quagga/bfd/toggleNeighbor/',
'options':{selection:false, multiSelect:false}
}
);
});
</script>
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<br/>
<button class="btn btn-primary" id="reconfigureAct"
data-endpoint='/api/quagga/service/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring BFD') }}"
type="button"
></button>
<br/><br/>
</div>
</div>
</section>
{{ partial("layout_partials/base_dialog",['fields':formDialogEditBFDNeighbor,'id':'DialogEditBFDNeighbor','label':lang._('Edit Neighbor')])}}
@@ -1,6 +1,6 @@
{#
OPNsense® is Copyright © 2014 2024 by Deciso B.V.
OPNsense® is Copyright © 2014 2025 by Deciso B.V.
Copyright (C) 2017 Fabian Franz
Copyright (C) 2017 - 2020 Michael Muenz <m.muenz@gmail.com>
All rights reserved.
@@ -27,6 +27,77 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
#}
<script>
$(document).ready(function() {
mapDataToFormUI({'frm_bgp_settings':"/api/quagga/bgp/get"}).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('quagga');
});
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/quagga/bgp/set", 'frm_bgp_settings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status) {
updateServiceControlUI('quagga');
}
});
$("#grid-neighbors").UIBootgrid({
'search':'/api/quagga/bgp/searchNeighbor',
'get':'/api/quagga/bgp/getNeighbor/',
'set':'/api/quagga/bgp/setNeighbor/',
'add':'/api/quagga/bgp/addNeighbor/',
'del':'/api/quagga/bgp/delNeighbor/',
'toggle':'/api/quagga/bgp/toggleNeighbor/'
});
$("#grid-aspaths").UIBootgrid({
'search':'/api/quagga/bgp/searchAspath',
'get':'/api/quagga/bgp/getAspath/',
'set':'/api/quagga/bgp/setAspath/',
'add':'/api/quagga/bgp/addAspath/',
'del':'/api/quagga/bgp/delAspath/',
'toggle':'/api/quagga/bgp/toggleAspath/'
});
$("#grid-prefixlists").UIBootgrid({
'search':'/api/quagga/bgp/searchPrefixlist',
'get':'/api/quagga/bgp/getPrefixlist/',
'set':'/api/quagga/bgp/setPrefixlist/',
'add':'/api/quagga/bgp/addPrefixlist/',
'del':'/api/quagga/bgp/delPrefixlist/',
'toggle':'/api/quagga/bgp/togglePrefixlist/'
});
$("#grid-communitylists").UIBootgrid({
'search':'/api/quagga/bgp/searchCommunitylist',
'get':'/api/quagga/bgp/getCommunitylist/',
'set':'/api/quagga/bgp/setCommunitylist/',
'add':'/api/quagga/bgp/addCommunitylist/',
'del':'/api/quagga/bgp/delCommunitylist/',
'toggle':'/api/quagga/bgp/toggleCommunitylist/'
});
$("#grid-routemaps").UIBootgrid({
'search':'/api/quagga/bgp/searchRoutemap',
'get':'/api/quagga/bgp/getRoutemap/',
'set':'/api/quagga/bgp/setRoutemap/',
'add':'/api/quagga/bgp/addRoutemap/',
'del':'/api/quagga/bgp/delRoutemap/',
'toggle':'/api/quagga/bgp/toggleRoutemap/'
});
$("#grid-peergroups").UIBootgrid({
'search':'/api/quagga/bgp/searchPeergroup',
'get':'/api/quagga/bgp/getPeergroup/',
'set':'/api/quagga/bgp/setPeergroup/',
'add':'/api/quagga/bgp/addPeergroup/',
'del':'/api/quagga/bgp/delPeergroup/',
'toggle':'/api/quagga/bgp/togglePeergroup/'
});
});
</script>
<!-- Navigation bar -->
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
<li class="active"><a data-toggle="tab" href="#general">{{ lang._('General') }}</a></li>
@@ -41,10 +112,6 @@ POSSIBILITY OF SUCH DAMAGE.
<div id="general" class="tab-pane fade in active">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':bgpForm,'id':'frm_bgp_settings'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
</div>
<div id="neighbors" class="tab-pane fade in">
@@ -67,11 +134,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="10"></td>
<td colspan="1">
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -94,11 +160,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -122,11 +187,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -150,11 +214,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -181,10 +244,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -210,10 +273,10 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="10"></td>
<td colspan="1">
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -221,102 +284,20 @@ POSSIBILITY OF SUCH DAMAGE.
</div>
</div>
<script>
function quagga_update_status() {
updateServiceControlUI('quagga');
}
$(document).ready(function() {
var data_get_map = {'frm_bgp_settings':"/api/quagga/bgp/get"};
mapDataToFormUI(data_get_map).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
});
quagga_update_status();
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/quagga/bgp/set",formid='frm_bgp_settings',callback_ok=function(){
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
quagga_update_status();
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
});
/* allow a user to manually reload the service (for forms which do not do it automatically) */
$('.reload_btn').click(function reload_handler() {
$(".reloadAct_progress").addClass("fa-spin");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
quagga_update_status();
$(".reloadAct_progress").removeClass("fa-spin");
});
});
$("#grid-neighbors").UIBootgrid(
{ 'search':'/api/quagga/bgp/searchNeighbor',
'get':'/api/quagga/bgp/getNeighbor/',
'set':'/api/quagga/bgp/setNeighbor/',
'add':'/api/quagga/bgp/addNeighbor/',
'del':'/api/quagga/bgp/delNeighbor/',
'toggle':'/api/quagga/bgp/toggleNeighbor/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-aspaths").UIBootgrid(
{ 'search':'/api/quagga/bgp/searchAspath',
'get':'/api/quagga/bgp/getAspath/',
'set':'/api/quagga/bgp/setAspath/',
'add':'/api/quagga/bgp/addAspath/',
'del':'/api/quagga/bgp/delAspath/',
'toggle':'/api/quagga/bgp/toggleAspath/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-prefixlists").UIBootgrid(
{ 'search':'/api/quagga/bgp/searchPrefixlist',
'get':'/api/quagga/bgp/getPrefixlist/',
'set':'/api/quagga/bgp/setPrefixlist/',
'add':'/api/quagga/bgp/addPrefixlist/',
'del':'/api/quagga/bgp/delPrefixlist/',
'toggle':'/api/quagga/bgp/togglePrefixlist/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-communitylists").UIBootgrid(
{ 'search':'/api/quagga/bgp/searchCommunitylist',
'get':'/api/quagga/bgp/getCommunitylist/',
'set':'/api/quagga/bgp/setCommunitylist/',
'add':'/api/quagga/bgp/addCommunitylist/',
'del':'/api/quagga/bgp/delCommunitylist/',
'toggle':'/api/quagga/bgp/toggleCommunitylist/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-routemaps").UIBootgrid(
{ 'search':'/api/quagga/bgp/searchRoutemap',
'get':'/api/quagga/bgp/getRoutemap/',
'set':'/api/quagga/bgp/setRoutemap/',
'add':'/api/quagga/bgp/addRoutemap/',
'del':'/api/quagga/bgp/delRoutemap/',
'toggle':'/api/quagga/bgp/toggleRoutemap/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-peergroups").UIBootgrid(
{ 'search':'/api/quagga/bgp/searchPeergroup',
'get':'/api/quagga/bgp/getPeergroup/',
'set':'/api/quagga/bgp/setPeergroup/',
'add':'/api/quagga/bgp/addPeergroup/',
'del':'/api/quagga/bgp/delPeergroup/',
'toggle':'/api/quagga/bgp/togglePeergroup/',
'options':{selection:false, multiSelect:false}
}
);
});
</script>
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<br/>
<button class="btn btn-primary" id="reconfigureAct"
data-endpoint='/api/quagga/service/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring BGP') }}"
type="button"
></button>
<br/><br/>
</div>
</div>
</section>
{{ partial("layout_partials/base_dialog",['fields':formDialogEditBGPNeighbor,'id':'DialogEditBGPNeighbor','label':lang._('Edit Neighbor')])}}
{{ partial("layout_partials/base_dialog",['fields':formDialogEditBGPASPaths,'id':'DialogEditBGPASPaths','label':lang._('Edit AS Paths')])}}
@@ -1,6 +1,6 @@
{#
OPNsense® is Copyright © 2014 2017 by Deciso B.V.
OPNsense® is Copyright © 2014 2025 by Deciso B.V.
This file is Copyright © 2017 by Fabian Franz
All rights reserved.
@@ -26,32 +26,43 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
#}
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
<script>
$( document ).ready(function() {
var data_get_map = {'frm_general_settings':"/api/quagga/general/get"};
mapDataToFormUI(data_get_map).done(function(data){
mapDataToFormUI({'frm_general_settings':"/api/quagga/general/get"}).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('quagga');
});
updateServiceControlUI('quagga');
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/quagga/general/set", formid='frm_general_settings',callback_ok=function(){
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
updateServiceControlUI('quagga');
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
}, true);
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/quagga/general/set", 'frm_general_settings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status) {
updateServiceControlUI('quagga');
}
});
});
</script>
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}}
</div>
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<br/>
<button class="btn btn-primary" id="reconfigureAct"
data-endpoint='/api/quagga/service/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring BFD') }}"
type="button"
></button>
<br/><br/>
</div>
</div>
</section>
@@ -1,6 +1,6 @@
{#
OPNsense® is Copyright © 2014 2017 by Deciso B.V.
OPNsense® is Copyright © 2014 2025 by Deciso B.V.
This file is Copyright © 2017 by Fabian Franz
All rights reserved.
@@ -27,25 +27,78 @@ POSSIBILITY OF SUCH DAMAGE.
#}
<!-- Navigation bar -->
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
<li class="active"><a data-toggle="tab" href="#general">{{ lang._('General') }}</a></li>
<li><a data-toggle="tab" href="#networks">{{ lang._('Networks') }}</a></li>
<li><a data-toggle="tab" href="#interfaces">{{ lang._('Interfaces') }}</a></li>
<li><a data-toggle="tab" href="#prefixlists">{{ lang._('Prefix Lists') }}</a></li>
<li><a data-toggle="tab" href="#routemaps">{{ lang._('Route Maps') }}</a></li>
</ul>
<div class="tab-content content-box tab-content">
<div id="general" class="tab-pane fade in active">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_ospf_settings'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
</div>
<script>
function quagga_update_status() {
updateServiceControlUI('quagga');
}
$( document ).ready(function() {
mapDataToFormUI({'frm_ospf_settings':"/api/quagga/ospfsettings/get"}).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('quagga');
});
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/quagga/ospfsettings/set", 'frm_ospf_settings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status) {
updateServiceControlUI('quagga');
}
});
$("#grid-networks").UIBootgrid({
'search':'/api/quagga/ospfsettings/searchNetwork',
'get':'/api/quagga/ospfsettings/getNetwork/',
'set':'/api/quagga/ospfsettings/setNetwork/',
'add':'/api/quagga/ospfsettings/addNetwork/',
'del':'/api/quagga/ospfsettings/delNetwork/',
'toggle':'/api/quagga/ospfsettings/toggleNetwork/'
});
$("#grid-interfaces").UIBootgrid({
'search':'/api/quagga/ospfsettings/searchInterface',
'get':'/api/quagga/ospfsettings/getInterface/',
'set':'/api/quagga/ospfsettings/setInterface/',
'add':'/api/quagga/ospfsettings/addInterface/',
'del':'/api/quagga/ospfsettings/delInterface/',
'toggle':'/api/quagga/ospfsettings/toggleInterface/'
});
$("#grid-prefixlists").UIBootgrid({
'search':'/api/quagga/ospfsettings/searchPrefixlist',
'get':'/api/quagga/ospfsettings/getPrefixlist/',
'set':'/api/quagga/ospfsettings/setPrefixlist/',
'add':'/api/quagga/ospfsettings/addPrefixlist/',
'del':'/api/quagga/ospfsettings/delPrefixlist/',
'toggle':'/api/quagga/ospfsettings/togglePrefixlist/'
});
$("#grid-routemaps").UIBootgrid({
'search':'/api/quagga/ospfsettings/searchRoutemap',
'get':'/api/quagga/ospfsettings/getRoutemap/',
'set':'/api/quagga/ospfsettings/setRoutemap/',
'add':'/api/quagga/ospfsettings/addRoutemap/',
'del':'/api/quagga/ospfsettings/delRoutemap/',
'toggle':'/api/quagga/ospfsettings/toggleRoutemap/'
});
});
</script>
<!-- Navigation bar -->
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
<li class="active"><a data-toggle="tab" href="#general">{{ lang._('General') }}</a></li>
<li><a data-toggle="tab" href="#networks">{{ lang._('Networks') }}</a></li>
<li><a data-toggle="tab" href="#interfaces">{{ lang._('Interfaces') }}</a></li>
<li><a data-toggle="tab" href="#prefixlists">{{ lang._('Prefix Lists') }}</a></li>
<li><a data-toggle="tab" href="#routemaps">{{ lang._('Route Maps') }}</a></li>
</ul>
<div class="tab-content content-box tab-content">
<!-- Tab: General -->
<div id="general" class="tab-pane fade in active">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_ospf_settings'])}}
</div>
<!-- Tab: Networks -->
<div id="networks" class="tab-pane fade in">
<table id="grid-networks" class="table table-responsive" data-editDialog="DialogEditNetwork">
@@ -63,17 +116,15 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- Tab: Interfaces -->
<div id="interfaces" class="tab-pane fade in">
<table id="grid-interfaces" class="table table-responsive" data-editDialog="DialogEditInterface">
@@ -85,22 +136,22 @@ POSSIBILITY OF SUCH DAMAGE.
<th data-column-id="authtype" data-type="string" data-visible="true">{{ lang._('Authentication Type') }}</th>
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
<th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
</tr>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- Tab: Prefixlists -->
<div id="prefixlists" class="tab-pane fade in">
<table id="grid-prefixlists" class="table table-responsive" data-editDialog="DialogEditPrefixLists">
<thead>
@@ -118,16 +169,16 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<!-- <button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button> -->
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- Tab: Routemaps -->
<div id="routemaps" class="tab-pane fade in">
<table id="grid-routemaps" class="table table-responsive" data-editDialog="DialogEditRouteMaps">
<thead>
@@ -146,95 +197,30 @@ POSSIBILITY OF SUCH DAMAGE.
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span> {{ lang._('Reload Service') }}</button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<button class="btn btn-primary __mb __mt" id="reconfigureAct"
data-endpoint='/api/quagga/service/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring OSPFv3') }}"
data-service-widget="quagga"
type="button"
></button>
</div>
</div>
<script>
function quagga_update_status() {
updateServiceControlUI('quagga');
}
$( document ).ready(function() {
var data_get_map = {'frm_ospf_settings':"/api/quagga/ospfsettings/get"};
mapDataToFormUI(data_get_map).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
});
quagga_update_status();
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/quagga/ospfsettings/set",formid='frm_ospf_settings',callback_ok=function(){
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
quagga_update_status();
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
});
/* allow a user to manually reload the service (for forms which do not do it automatically) */
$('.reload_btn').click(function reload_handler() {
$(".reloadAct_progress").addClass("fa-spin");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
quagga_update_status();
$(".reloadAct_progress").removeClass("fa-spin");
});
});
$("#grid-networks").UIBootgrid(
{ 'search':'/api/quagga/ospfsettings/searchNetwork',
'get':'/api/quagga/ospfsettings/getNetwork/',
'set':'/api/quagga/ospfsettings/setNetwork/',
'add':'/api/quagga/ospfsettings/addNetwork/',
'del':'/api/quagga/ospfsettings/delNetwork/',
'toggle':'/api/quagga/ospfsettings/toggleNetwork/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-interfaces").UIBootgrid(
{ 'search':'/api/quagga/ospfsettings/searchInterface',
'get':'/api/quagga/ospfsettings/getInterface/',
'set':'/api/quagga/ospfsettings/setInterface/',
'add':'/api/quagga/ospfsettings/addInterface/',
'del':'/api/quagga/ospfsettings/delInterface/',
'toggle':'/api/quagga/ospfsettings/toggleInterface/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-prefixlists").UIBootgrid(
{ 'search':'/api/quagga/ospfsettings/searchPrefixlist',
'get':'/api/quagga/ospfsettings/getPrefixlist/',
'set':'/api/quagga/ospfsettings/setPrefixlist/',
'add':'/api/quagga/ospfsettings/addPrefixlist/',
'del':'/api/quagga/ospfsettings/delPrefixlist/',
'toggle':'/api/quagga/ospfsettings/togglePrefixlist/',
'options':{selection:false, multiSelect:false}
}
);
$("#grid-routemaps").UIBootgrid(
{ 'search':'/api/quagga/ospfsettings/searchRoutemap',
'get':'/api/quagga/ospfsettings/getRoutemap/',
'set':'/api/quagga/ospfsettings/setRoutemap/',
'add':'/api/quagga/ospfsettings/addRoutemap/',
'del':'/api/quagga/ospfsettings/delRoutemap/',
'toggle':'/api/quagga/ospfsettings/toggleRoutemap/',
'options':{selection:false, multiSelect:false}
}
);
});
</script>
</section>
{{ partial("layout_partials/base_dialog",['fields':formDialogEditNetwork,'id':'DialogEditNetwork','label':lang._('Edit Network')])}}
{{ partial("layout_partials/base_dialog",['fields':formDialogEditInterface,'id':'DialogEditInterface','label':lang._('Edit Interface')])}}
@@ -1,5 +1,5 @@
{#
# Copyright (c) 2014-2024 Deciso B.V.
# Copyright (c) 2014-2025 Deciso B.V.
# Copyright (c) 2017 Fabian Franz
# Copyright (c) 2017 Michael Muenz <m.muenz@gmail.com>
# All rights reserved.
@@ -32,18 +32,17 @@
mapDataToFormUI({'frm_ospf6_settings':"/api/quagga/ospf6settings/get"}).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('quagga');
});
updateServiceControlUI('quagga');
// link save button to API set action
$("#saveAct").SimpleActionButton({
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/quagga/ospf6settings/set", 'frm_ospf6_settings', function(){
dfObj.resolve();
});
saveFormToEndpoint("/api/quagga/ospf6settings/set", 'frm_ospf6_settings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status) {
updateServiceControlUI('quagga');
}
});
@@ -53,11 +52,7 @@
'set':'/api/quagga/ospf6settings/setNetwork/',
'add':'/api/quagga/ospf6settings/addNetwork/',
'del':'/api/quagga/ospf6settings/delNetwork/',
'toggle':'/api/quagga/ospf6settings/toggleNetwork/',
'options':{
selection:false,
multiSelect:false
}
'toggle':'/api/quagga/ospf6settings/toggleNetwork/'
});
$("#grid-interfaces").UIBootgrid({
'search':'/api/quagga/ospf6settings/searchInterface',
@@ -65,11 +60,7 @@
'set':'/api/quagga/ospf6settings/setInterface/',
'add':'/api/quagga/ospf6settings/addInterface/',
'del':'/api/quagga/ospf6settings/delInterface/',
'toggle':'/api/quagga/ospf6settings/toggleInterface/',
'options':{
selection:false,
multiSelect:false
}
'toggle':'/api/quagga/ospf6settings/toggleInterface/'
});
$("#grid-prefixlists").UIBootgrid({
'search':'/api/quagga/ospf6settings/searchPrefixlist',
@@ -77,11 +68,7 @@
'set':'/api/quagga/ospf6settings/setPrefixlist/',
'add':'/api/quagga/ospf6settings/addPrefixlist/',
'del':'/api/quagga/ospf6settings/delPrefixlist/',
'toggle':'/api/quagga/ospf6settings/togglePrefixlist/',
'options':{
selection:false,
multiSelect:false
}
'toggle':'/api/quagga/ospf6settings/togglePrefixlist/'
});
$("#grid-routemaps").UIBootgrid({
'search':'/api/quagga/ospf6settings/searchRoutemap',
@@ -89,11 +76,7 @@
'set':'/api/quagga/ospf6settings/setRoutemap/',
'add':'/api/quagga/ospf6settings/addRoutemap/',
'del':'/api/quagga/ospf6settings/delRoutemap/',
'toggle':'/api/quagga/ospf6settings/toggleRoutemap/',
'options':{
selection:false,
multiSelect:false
}
'toggle':'/api/quagga/ospf6settings/toggleRoutemap/'
});
// hook checkbox item with conditional options
@@ -142,10 +125,11 @@
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
</td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
@@ -168,9 +152,10 @@
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -195,9 +180,10 @@
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -223,9 +209,10 @@
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
@@ -236,7 +223,7 @@
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<button class="btn btn-primary __mb __mt" id="saveAct"
<button class="btn btn-primary __mb __mt" id="reconfigureAct"
data-endpoint='/api/quagga/service/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring OSPFv3') }}"
@@ -1,6 +1,6 @@
{#
OPNsense® is Copyright © 2014 2017 by Deciso B.V.
OPNsense® is Copyright © 2014 2025 by Deciso B.V.
This file is Copyright © 2017 by Fabian Franz
All rights reserved.
@@ -27,33 +27,43 @@ POSSIBILITY OF SUCH DAMAGE.
#}
<script>
$( document ).ready(function() {
mapDataToFormUI({'frm_rip_settings':"/api/quagga/rip/get"}).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('quagga');
});
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = new $.Deferred();
saveFormToEndpoint("/api/quagga/rip/set", 'frm_rip_settings', function () { dfObj.resolve(); }, true, function () { dfObj.reject(); });
return dfObj;
},
onAction: function(data, status) {
updateServiceControlUI('quagga');
}
});
});
</script>
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':ripForm,'id':'frm_rip_settings'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
<script>
$(document).ready(function() {
var data_get_map = {'frm_rip_settings':"/api/quagga/rip/get"};
mapDataToFormUI(data_get_map).done(function(data){
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
});
<section class="page-content-main">
<div class="content-box">
<div class="col-md-12">
<br/>
<button class="btn btn-primary" id="reconfigureAct"
data-endpoint='/api/quagga/service/reconfigure'
data-label="{{ lang._('Apply') }}"
data-error-title="{{ lang._('Error reconfiguring BFD') }}"
type="button"
></button>
<br/><br/>
</div>
</div>
</section>
updateServiceControlUI('quagga');
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/quagga/rip/set",formid='frm_rip_settings',callback_ok=function(){
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/quagga/service/reconfigure", sendData={}, callback=function(data,status) {
updateServiceControlUI('quagga');
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
});
});
</script>