1 {% extends "b3theme/base.html" %}
4 <link href="{{STATIC_URL}}b3theme/css/plugins/dataTables/dataTables.bootstrap.css" rel="stylesheet">
6 {% block pagejsbodttom %}
8 <script type="text/javascript" src="{{STATIC_URL}}js/jquery.dataTables.js"></script>
9 <script type="text/javascript" src="{{STATIC_URL}}js/datatables_bootstrap.js"></script>
13 {% block title %}{% trans "My rules" %}{% endblock %}
14 {% block contentplaceholder %}
17 <div class="col-md-12">
18 <h1 class="page-header">{% trans "My rules" %} </h1>
25 <div class="col-md-10">
26 <div class="panel panel-primary">
27 <div class="panel-heading"> <i class="fa fa-shield"></i> Firewall Rules
30 <div class="panel-body">
33 <div class="table-responsive">
34 <table class="table table-striped table-bordered" id="routes_table">
38 <th>{% trans "Name" %}</th>
39 <th>{% trans "Match" %}</th>
40 <th style="text-align: center;">{% trans "Then" %}</th>
41 <th style="text-align: center; ">{% trans "Status" %}</th>
42 <th style="text-align: center;">{% trans "Applier" %}</th>
43 <th style="text-align: center;">{% trans "Expires" %}</th>
44 <th style="text-align: center;">{% trans "Response" %}</th>
45 <th style="text-align: center;">{% trans "Actions" %}</th>
56 <div class="col-md-2">
57 <div class="panel panel-default">
58 <div class="panel-heading">
59 <i class="fa fa-tags"></i> {% trans "Shortcuts" %}
61 <!-- /.panel-heading -->
62 <div class="panel-body">
63 <a class="btn btn-sm btn-outline btn-success" id="routebutton" href="{% url add-route %}"><i class="fa fa-plus-circle"></i> {% trans "Add Rule" %}</a>
64 <a class="btn btn-sm btn-outline btn-info" href="{% url user-profile %}"><i class="fa fa-user"></i> {% trans "My Profile" %}</a>
70 <div class="chat-panel panel panel-info">
71 <div class="panel-heading">
72 <i class="fa fa-comment fa-fw"></i> Live status
74 <!-- /.panel-heading -->
75 <div class="panel-body">
76 {% include "polldash.html" %}
87 {% block pagejsbottom %}
88 <script src="{{STATIC_URL}}js/dataTableslatest/jquery.dataTables.min.js"></script>
89 <script src="{{STATIC_URL}}js/dataTableslatest/dataTables.bootstrap.js"></script>
90 {% if user.is_authenticated %}
91 <script type="text/javascript" src="{% url load-js 'poller' %}"></script>
94 <script type="text/javascript">
95 var filterbtns = '<div class="btn-group col-centered">\
96 <button type="button" class="btn btn-outline btn-sm btn-success" name="status_filter" value="ACTIVE" id="show_active">ACTIVE</button>\
97 <button type="button" class="btn btn-outline btn-sm btn-info" name="status_filter" value="PENDING" id="show_pending">PENDING</button>\
98 <button type="button" class="btn btn-outline btn-sm btn-warning" name="status_filter" value="ERROR" id="show_error">ERROR</button>\
99 <button type="button" class="btn btn-outline btn-sm btn-default" name="status_filter" value="DEACTIVATED" id="show_deactivated">DEACTIVATED</button>\
103 $.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
105 // DataTables 1.10 compatibility - if 1.10 then versionCheck exists.
106 // 1.10s API has ajax reloading built in, so we use those abilities
108 if ( $.fn.dataTable.versionCheck ) {
109 var api = new $.fn.dataTable.Api( oSettings );
112 api.ajax.url( sNewSource ).load( fnCallback, !bStandingRedraw );
115 api.ajax.reload( fnCallback, !bStandingRedraw );
120 if ( sNewSource !== undefined && sNewSource !== null ) {
121 oSettings.sAjaxSource = sNewSource;
124 // Server-side processing should just call fnDraw
125 if ( oSettings.oFeatures.bServerSide ) {
130 this.oApi._fnProcessingDisplay( oSettings, true );
132 var iStart = oSettings._iDisplayStart;
135 this.oApi._fnServerParams( oSettings, aData );
137 oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aData, function(json) {
138 /* Clear the old information from the table */
139 that.oApi._fnClearTable( oSettings );
141 /* Got the data - add it to the table */
142 var aData = (oSettings.sAjaxDataProp !== "") ?
143 that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json;
145 for ( var i=0 ; i<aData.length ; i++ )
147 that.oApi._fnAddData( oSettings, aData[i] );
150 oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
154 if ( bStandingRedraw === true )
156 oSettings._iDisplayStart = iStart;
157 that.oApi._fnCalculateEnd( oSettings );
158 that.fnDraw( false );
161 that.oApi._fnProcessingDisplay( oSettings, false );
163 /* Callback user function - for event handlers etc */
164 if ( typeof fnCallback == 'function' && fnCallback !== null )
166 fnCallback( oSettings );
174 var last_element = false;
175 var refreshUrl = "{% url group-routes-ajax %}";
176 $(document).ready( function(){
180 oTable = $('#routes_table').dataTable( {
188 "sDom": "<'row'<'col-xs-4'l><'col-xs-4'<'#filterplaceholder'>><'col-xs-4'f>><'row'<'col-xs-6'i><'col-xs-6'p>>tr<'row'<'col-xs-6'i><'col-xs-6'p>>",
189 "iDisplayLength": 20,
191 "sAjaxSource": refreshUrl,
192 "bDeferRender": true,
193 "fnInitComplete": function(oSettings, json) {
194 oTable.fnSetColumnVis( 0,false );
197 $('body').on('click', '.revertbutton', function () {
199 my.parent().html(oldhtml);
200 last_element = false;
203 $('body').on('click', ".del_buttonpre", function(){
205 if (last_element != false){
206 last_element.html(oldhtml);
208 oldhtml = my.parent().html();
209 last_element = my.parent();
210 var routename = $(this).data("routename");
211 var btn = '<a href="#" data-toggle="tooltip" title="This will deactivate your rule" data-routename="'+routename+'" class="del_button btn btn-sm btn-warning"> {% trans "Deactivate" %}</a>'
212 var back = '<a href="#" class="revertbutton btn btn-sm btn-info"><i class="fa fa-undo"></i></a>';
213 my.parent().html(back+" "+btn);
217 $('body').on('click', ".del_button", function(){
218 last_element = false;
220 my.html('Deactivating...')
221 var routename = $(this).data("routename");
222 var delurl = "{% url delete-route 'route_placeholder'%}".replace('route_placeholder', routename.toString());
227 success: function(data) {
228 oTable.fnReloadAjax(refreshUrl);
235 {"mData":"id", "bSearchable": false,"bSortable": false, "bvisible":false},
236 {"mData":"name", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
237 "mRender": function (data, type, full) {
238 if (!full.comments.trim()) {
239 return '<small>'+data+'</small>';
241 return '<a rel="tooltip" href="#" data-toggle="tooltip" data-placement="top" title='+full.comments+'><small>'+data+'</small>'
244 {"mData":"match", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
245 "mRender": function (data, type, full) {
246 return '<small>'+data+'</small>';
249 {"mData":"then", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
250 "mRender": function (data, type, full) {
251 return '<small>'+data+'</small>';
254 {"mData":"status", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
255 "mRender": function (data, type, full) {
257 if (status == "EXPIRED" ||status == "ADMININACTIVE" || status == "INACTIVE" || status == "OUTOFSYNC"){
258 if (status == "EXPIRED" ||status == "ADMININACTIVE" || status == "INACTIVE" ){
259 return '<span class="label label-default">DEACTIVATED</span>';
263 if (status == "OUTOFSYNC"){
264 return '<span class="label label-danger">ERROR</span>';
272 if (status == 'ACTIVE'){
273 return '<span class="label label-success">'+status+'</span>';
276 if (status == 'PENDING'){
277 return '<span class="label label-info">'+status+'</span>';
280 return '<span class="label label-danger">'+status+'</span>';
286 {"mData":"applier", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
287 "mRender": function (data, type, full) {
288 return '<small>'+data+'</small>';
291 {"mData":"expires", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
292 "mRender": function (data, type, full) {
293 return '<small>'+data+'</small>';
295 {"mData":"response", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
296 "mRender": function (data, type, full) {
297 status = full.status;
298 toolt = '<a rel="tooltip" href="#" data-toggle="tooltip" data-placement="top"';
299 if (status == "EXPIRED" ||status == "ADMININACTIVE" || status == "INACTIVE" || status == "OUTOFSYNC"){
300 if (status == "INACTIVE" ){
301 title = "{% trans 'Deactivated by user' %}";
303 if (status == "ADMININACTIVE" ){
304 title = "{% trans 'Deactivated by administrator' %}";
306 if (status == "EXPIRED" ){
307 title = "{% trans 'Deactivated due to expiration' %}";
309 if (status == "OUTOFSYNC" ){
310 title = "{% trans 'Syncronization error. Configuration in device differs from rule' %}";
312 return toolt+" title=\""+title+"\">"+"<small>{% trans 'Rule expired' %}</small>"+"</a>";
314 if (status == "PENDING"){
315 return '<img src="{{STATIC_URL}}dots.gif">';
317 return "<small>"+full.response+"</small>";
321 {"mData":"comments", "sClass" : "alignCenter","bSearchable": true,"bSortable": true,
322 "mRender": function (data, type, full) {
323 status = full.status;
325 editurl = "{% url edit-route 'routename' %}".replace('routename', full.name.toString());
326 if (status == "ACTIVE" ){
327 btn = '<a href="'+editurl+'" class="btn-info btn btn-sm btn-outline">{% trans "Edit" %}</a>';
328 btn = btn + ' <button class="del_buttonpre btn-warning btn btn-sm btn-outline" id="'+full.name+'" data-routename="'+full.name+'">{% trans "Deactivate" %}</button>';
330 if (status == 'EXPIRED' || status == 'ADMININACTIVE' || status == 'INACTIVE' ){
331 btn = '<a href="'+editurl+'" class="btn-info btn btn-sm btn-outline" id="edit_button_{{route.pk}}">{% trans "Reactivate" %}</a>';
333 if (status == "OUTOFSYNC" ){
334 btn = '<a href="'+editurl+'" class="btn-info btn btn-sm btn-outline" id="edit_button_{{route.pk}}">{% trans "Resync" %}</a>';
336 if (status == "ERROR" ){
337 btn = '<a href="'+editurl+'" class="btn-info btn btn-sm btn-outline" id="edit_button_{{route.pk}}">{% trans "Fix it!" %}</a>';
345 $('#filterplaceholder').html(filterbtns);
349 $('body').on('click', 'button[name="status_filter"]', function(){
351 var checkboxs = document.getElementsByName('status_filter');
352 $(this).button('toggle');
353 for (var i = 0, inp; inp = checkboxs[i]; i++) {
354 if (inp.type.toLowerCase() == 'button' && $(inp).hasClass('active')) {
355 reg_exp = reg_exp + inp.value + '|';
358 //passing an empty string will result in no filter
359 //thus, it must be set to something that will not exist in the column
363 oTable.fnFilter(reg_exp.slice(0, -1), 4, true, false, false);
364 console.log(reg_exp.slice(0, -1))
368 $(window).resize(function() {
369 clearTimeout(window.refresh_size);
370 window.refresh_size = setTimeout(function() { update_size(); }, 250);
373 var update_size = function() {
374 $(oTable).css({ width: $(oTable).parent().width() });
375 pw=$(oTable).parent().width();
376 tw=$(oTable).width();
378 oTable.fnSetColumnVis( 7,false );
379 oTable.fnSetColumnVis( 5,false );
381 oTable.fnSetColumnVis( 7,true );
382 oTable.fnSetColumnVis( 5,true );
384 oTable.fnAdjustColumnSizing();
387 $("body").tooltip({ selector: '[data-toggle="tooltip"]' });
390 <style type="text/css">