Commit 0d2e4cb5 authored by Stauros Kroustouris's avatar Stauros Kroustouris

move base template outside of theme file and fix lint errors

parent b44b6bb3
......@@ -19,19 +19,28 @@
from django.contrib import admin
from peers.models import *
from flowspec.forms import *
from django.conf import settings
from peers.models import PeerRange, TechcEmail, Peer
from django import forms
from django.forms import ModelForm
from django.contrib.admin.widgets import FilteredSelectMultiple
class PeerAdminForm(ModelForm):
networks=forms.ModelMultipleChoiceField(PeerRange.objects.all(),widget=
FilteredSelectMultiple("PeerRange",True), required=False)
techc_emails=forms.ModelMultipleChoiceField(TechcEmail.objects.all(),widget=
FilteredSelectMultiple("TechcEmail",True), required=False)
networks = forms.ModelMultipleChoiceField(
PeerRange.objects.all(),
widget=FilteredSelectMultiple("PeerRange", True),
required=False
)
techc_emails = forms.ModelMultipleChoiceField(
TechcEmail.objects.all(),
widget=FilteredSelectMultiple("TechcEmail", True),
required=False
)
class Meta:
model= Peer
model = Peer
class PeerAdmin(admin.ModelAdmin):
form = PeerAdminForm
......
......@@ -19,26 +19,32 @@
from django.db import models
from utils.whois import *
from django.contrib.auth.models import User
from django.conf import settings
class PeerRange(models.Model):
network = models.CharField(max_length=128)
def __unicode__(self):
return self.network
class Meta:
db_table = u'peer_range'
ordering = ['network']
managed = settings.PEER_RANGE_MANAGED_TABLE
class TechcEmail(models.Model):
email = models.CharField(max_length=352, db_column="email")
def __unicode__(self):
return self.email
class Meta:
db_table="techc_email"
db_table = "techc_email"
managed = settings.PEER_TECHC_MANAGED_TABLE
class Peer(models.Model):
peer_id = models.AutoField(primary_key=True)
peer_name = models.CharField(max_length=128)
......@@ -51,16 +57,16 @@ class Peer(models.Model):
def __unicode__(self):
return self.peer_name
class Meta:
db_table = u'peer'
ordering = ['peer_name']
managed = settings.PEER_MANAGED_TABLE
def fill_networks(self):
network_range = []
networks_list = []
peer_as = "AS%s" %self.peer_as
peer_as = "AS%s" % self.peer_as
network_range = whois(peer_as)
if network_range:
for network_item in network_range:
......@@ -68,5 +74,3 @@ class Peer(models.Model):
networks_list.append(range)
self.networks = networks_list
self.save()
......@@ -16,11 +16,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from django.conf.urls.defaults import *
urlpatterns = patterns('poller.views',
('^$', 'main'),
url('^message/existing$', 'message_existing', name='fetch-existing'),
url('^message/updates$', 'message_updates', name='fetch-updates'))
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns(
'poller.views',
('^$', 'main'),
url('^message/existing$', 'message_existing', name='fetch-existing'),
url('^message/updates$', 'message_updates', name='fetch-updates')
)
......@@ -28,10 +28,8 @@ from django.template.loader import render_to_string
from django.http import HttpResponse
from gevent.event import Event
from django.conf import settings
#from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.conf import settings
import beanstalkc
......@@ -46,6 +44,7 @@ handler = logging.FileHandler(LOG_FILENAME)
handler.setFormatter(formatter)
logger.addHandler(handler)
def create_message(message, user, time):
data = {'id': str(uuid.uuid4()), 'body': message, 'user':user, 'time':time}
data['html'] = render_to_string('poll_message.html', dictionary={'message': data})
......@@ -56,10 +55,12 @@ def json_response(value, **kwargs):
kwargs.setdefault('content_type', 'text/javascript; charset=UTF-8')
return HttpResponse(json.dumps(value), **kwargs)
class Msgs(object):
cache_size = 500
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Msgs, cls).__new__(cls, *args, **kwargs)
......@@ -98,7 +99,7 @@ class Msgs(object):
self.user_cursor[user] = ''
return json_response({'messages': self.user_cache[user]})
return HttpResponseRedirect(reverse('group-routes'))
def message_new(self, mesg=None):
if mesg:
message = mesg['message']
......@@ -111,7 +112,7 @@ class Msgs(object):
except:
self.user_cache[user] = []
self.user_cache[user].append(msg)
if self.user_cache[user][-1] == self.user_cache[user][0]:
if self.user_cache[user][-1] == self.user_cache[user][0]:
self.user_cursor[user] = self.user_cache[user][-1]['id']
else:
self.user_cursor[user] = self.user_cache[user][-2]['id']
......@@ -120,11 +121,11 @@ class Msgs(object):
try:
assert(self.new_message_user_event[user])
except:
self.new_message_user_event[user] = Event()
self.new_message_user_event[user] = Event()
self.new_message_user_event[user].set()
self.new_message_user_event[user].clear()
return json_response(msg)
def message_updates(self, request):
if request.is_ajax():
cursor = {}
......@@ -137,7 +138,7 @@ class Msgs(object):
cursor[user] = self.user_cursor[user]
except:
return HttpResponse(content='', mimetype=None, status=400)
try:
if not isinstance(self.user_cache[user], list):
self.user_cache[user] = []
......@@ -164,13 +165,12 @@ class Msgs(object):
job.bury()
logger.info("Got New message")
self.message_new(msg)
def start_polling(self):
logger.info("Start Polling")
gevent.spawn(self.monitor_polls)
msgs = Msgs()
main = msgs.main
......
{% extends "b3theme/base.html" %}
{% extends "base.html" %}
{% load widget_tweaks %}
{% load i18n %}
......@@ -26,7 +26,7 @@
</div>
<!-- /.col-lg-12 -->
</div>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-danger">
......@@ -43,7 +43,7 @@
</div>
</div>
</div>
{% endblock %}
......
{% extends "b3theme/base.html" %}
{% extends "base.html" %}
{% load widget_tweaks %}
{% load i18n %}
......@@ -26,7 +26,7 @@
</div>
<!-- /.col-lg-12 -->
</div>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-danger">
......@@ -43,7 +43,7 @@
</div>
</div>
</div>
{% endblock %}
......
{% extends "b3theme/base.html" %}
{% extends "base.html" %}
{% load widget_tweaks %}
{% load i18n %}
......@@ -23,7 +23,7 @@
<link href="{{STATIC_URL}}b3theme/css/plugins/morris/morris-0.4.3.min.css" rel="stylesheet">
<link href="{{STATIC_URL}}b3theme/css/plugins/timeline/timeline.css" rel="stylesheet">
<link href="{{STATIC_URL}}datepicker/css/datepicker.css" rel="stylesheet">
{% endblock %}
{% block extraheadbottom %}
......@@ -34,7 +34,7 @@
#rule_form_container input:not([type="submit"]), #rule_form_container select {
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #DDDDDD;
-moz-border-radius: 3px; border-radius:3px; -webkit-border-radius: 3px;
-moz-border-radius: 3px; border-radius:3px; -webkit-border-radius: 3px;
float: left;
font-family: "Century Gothic",Helvetica,sans-serif;
font-size: 13px;
......@@ -46,7 +46,7 @@
#rule_form_container{
-moz-border-radius: 10px 10px 10px 10px; border-radius:10px; -webkit-border-radius: 10px;
-moz-box-shadow: 0 0 3px #AAAAAA; box-shadow: 0 0 3px #AAAAAA; -webkit-box-shadow: 0 0 3px #AAAAAA;
-moz-box-shadow: 0 0 3px #AAAAAA; box-shadow: 0 0 3px #AAAAAA; -webkit-box-shadow: 0 0 3px #AAAAAA;
background-color: #F9F9F9;
border: 2px solid #FFFFFF;
overflow: hidden;
......@@ -91,7 +91,7 @@
$("#id_protocol").select2();
$("#id_fragmenttype").select2();
$("#id_then").select2();
reArrangeSelect("id_sourceport");
$("#id_sourceport").select2({
placeholder: "Source Port(s)"
......@@ -111,8 +111,8 @@
$('#setFromAll').click(function(){
$("#id_source").val('0.0.0.0/0');
});
/*$('#id_then').attr("multiple", "");*/
/*
$( "#id_expires" ).datepicker({ dateFormat: 'yy-mm-dd' , maxDate: '+10d', minDate: '+1d', changeMonth: false, changeYear: false }).datepicker( $.datepicker.regional[ "el" ] );
......@@ -126,7 +126,7 @@
buttons: {
'{% trans "Add" %}': function() {
$.ajax({
url:"{% url add-rate-limit %}",
url:"{% url add-rate-limit %}",
data:$("#add_rl_form").serialize(),
type: "POST",
cache: false,
......@@ -139,7 +139,7 @@
}
catch (exception) {
$('#then_diag').html(data);
}
}
}
});
},
......@@ -167,7 +167,7 @@
$('#then_diag').dialog('open');
return false;
});
{% endcomment %}
$(".new_port").click(function(){
$(".new_port").hide();
......@@ -182,14 +182,14 @@
// $('#port_diag').dialog('open');
return false;
});
function reArrangeSelect(elementId) {
$("#"+elementId).html($("#"+elementId+" option").sort(function(a, b) {
return parseInt(a.text) == parseInt(b.text) ? 0 : parseInt(a.text) < parseInt(b.text) ? -1 : 1
}));
}
});
</script>
{% endblock %}
{% block contentplaceholder %}
......@@ -211,8 +211,8 @@
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<form method="POST" role="form" class="form-horizontal">
<form method="POST" role="form" class="form-horizontal">
{% csrf_token %}
{% load unescape %}
{% if form.non_field_errors %}
......@@ -221,7 +221,7 @@
</div>
{% endif %}
<fieldset {% if edit %} style="display:none;" {% endif %}>
<div class="form-group {% if form.name.errors %} has-error {% endif %}">
<label for="id_name" class="col-md-2 control-label"><b>{% trans "Name" %}</b></label>
<div class="col-md-8">
......@@ -248,7 +248,7 @@
{% endif %}
<fieldset>
<hr>
<div class="form-group {% if form.source.errors %} has-error {% endif %}">
<div class="form-group {% if form.source.errors %} has-error {% endif %}">
<label for="id_source" class="col-md-2 control-label"><b>{% trans "Source Address" %}</b></label>
<div class="col-md-6">
{% render_field form.source class+="form-control" placeholder=form.source.help_text %}
......@@ -259,8 +259,8 @@
<img src="{{STATIC_URL}}threat_source.png" style="height: 30px;"/> &nbsp;&nbsp;<button type="button" class="btn btn-md btn-info btn-outline" id="setFromAll">Any</button>
</div>
</div>
<div class="form-group {% if form.destination.errors %} has-error {% endif %}">
<div class="form-group {% if form.destination.errors %} has-error {% endif %}">
<label for="id_destination" class="col-md-2 control-label"><b>{% trans "Destination Address" %}</b></label>
<div class="col-md-6">
{% render_field form.destination class+="form-control" placeholder=form.destination.help_text %}
......@@ -271,8 +271,8 @@
<img src="{{STATIC_URL}}secure_destination.png" style="height: 30px;"/>
</div>
</div>
<div class="form-group {% if form.protocol.errors %} has-error {% endif %}">
<div class="form-group {% if form.protocol.errors %} has-error {% endif %}">
<label for="id_protocol" class="col-md-2 control-label" style="font-weight: normal;">{% trans "Protocol(s)" %}</label>
<div class="col-md-8">
{% render_field form.protocol class+="form-control" %}
......@@ -280,8 +280,8 @@
{% endif %}
</div>
</div>
<div class="form-group {% if form.fragmenttype.errors %} has-error {% endif %}">
<div class="form-group {% if form.fragmenttype.errors %} has-error {% endif %}">
<label for="id_fragmenttype" class="col-md-2 control-label" style="font-weight: normal;">{% trans "Fragment Type" %}</label>
<div class="col-md-8">
{% render_field form.fragmenttype class+="form-control" %}
......@@ -296,7 +296,7 @@
<div class="form-group ">
<label class="col-md-10" style="font-weight: normal;"><small>{% trans "Select source/destination port(s), or select common port(s) for both source/destination" %}</small></label>
</div>
<div class="form-group {% if form.sourceport.errors %} has-error {% endif %} {% if form.destinationport.errors %} has-error {% endif %} {% if form.port.errors %} has-error {% endif %}">
<div class="form-group {% if form.sourceport.errors %} has-error {% endif %} {% if form.destinationport.errors %} has-error {% endif %} {% if form.port.errors %} has-error {% endif %}">
<label for="id_sourceport" class="col-md-2 control-label" style="font-weight: normal;">{% trans "Src. Port(s)" %}</label>
<div class="col-md-2">
{% render_field form.sourceport class+="form-control" %}
......@@ -329,13 +329,13 @@
</div>
</div>
</fieldset>
<!-- END OF PORTS -->
<fieldset>
<hr>
<div class="form-group {% if form.then.errors %} has-error {% endif %}">
<div class="form-group {% if form.then.errors %} has-error {% endif %}">
<label for="id_then" class="col-md-2 control-label">{% trans "Then Actions" %}</label>
<div class="col-md-8">
{% render_field form.then class+="form-control" %}
......@@ -343,11 +343,11 @@
{% endif %}
</div>
</div>
</fieldset>
<fieldset>
<hr>
<div class="form-group {% if form.expires.errors %} has-error {% endif %}">
<div class="form-group {% if form.expires.errors %} has-error {% endif %}">
<label for="id_then" class="col-md-2 control-label">{% trans "Expires" %}</label>
<div class="col-md-8">
{% render_field form.expires class+="form-control datepicker" data-date-format="yyyy-mm-dd" %}
......@@ -356,12 +356,12 @@
</div>
</div>
</fieldset>
<fieldset>
<hr>
<div class="form-group {% if form.comments.errors %} has-error {% endif %}">
<div class="form-group {% if form.comments.errors %} has-error {% endif %}">
<label for="id_comments" class="col-md-2 control-label">{% trans "Comments" %}</label>
<div class="col-md-8">
{% render_field form.comments class+="form-control" placeholder="Give a short description of the intended use of this rule, that justifies the parameter selection above. Feel free to include any additional comments." %}
......@@ -370,7 +370,7 @@
</div>
</div>
</fieldset>
<div class="form-group">
<div class="col-md-2"></div>
......@@ -378,7 +378,7 @@
<button type="submit" id="applybutton" value="{% trans 'Apply' %}" class="btn btn-md btn-primary">Apply</button>
</div>
</div>
</form>
</div></div></div></div>
......
<!DOCTYPE html>
<html>
{% load i18n %}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GRNET FoD :: {% block title %}{% endblock %}</title>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
<link REL="SHORTCUT ICON" HREF="{{STATIC_URL}}favicon.ico">
<!-- Core CSS - Include with every page -->
<link href="{{STATIC_URL}}b3theme/css/bootstrap.min.css" rel="stylesheet">
<link href="{{STATIC_URL}}b3theme/font-awesome/css/font-awesome.css" rel="stylesheet">
{% block extrahead %}{% endblock %}
<!-- SB Admin CSS - Include with every page -->
<link href="{{STATIC_URL}}b3theme/css/sb-admin.css" rel="stylesheet">
{% block extraheadbottom %}{% endblock %}
<style>
.navbar-brand {
float: left;
font-size: 18px;
height: 20px;
line-height: 20px;
padding: 1px;
}
.footer {
border-top: 1px solid #E5E5E5;
color: #777777;
padding-bottom: 40px;
padding-top: 40px;
text-align: center;
}
</style>
</head>
<body>
<div id="wrapper">
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url dashboard %}"><img src="{{STATIC_URL}}fodlogo2.png">&nbsp;</a>
</div>
<!-- /.navbar-header -->
<ul class="nav navbar-top-links navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Language" %}: {% for lang in LANGUAGES %}{% ifequal LANGUAGE_CODE lang.0 %}{% trans lang.1 %}{% endifequal %}{% endfor %}<b class="caret"></b></a>
<ul class="dropdown-menu">
<form action="{% url django.views.i18n.set_language %}" method="post" style="display:inline;" id="langform">
{% csrf_token %}
<input name="next" type="hidden" value="{{ next }}" />
<input id="langsel" name="language" type="hidden" value="" />
</form>
{% for lang in LANGUAGES %}
<li>
<a class="select_lang" href="#" onclick="setlang('{{ lang.0 }}'); return false;" title="{{lang.1}}">{% trans lang.1 %}{% ifequal LANGUAGE_CODE lang.0 %} <i class="icon-ok"></i>{% endifequal %}</a>
</li>
{% endfor %}
</ul>
</li>
<!-- /.dropdown -->
{% if user.is_authenticated %}
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-user" role="menu" >
<li role="presentation" class="dropdown-header">{{user}}</li>
<li class="divider"></li>
{% if user.get_profile.peer %}
<li>
<a href="{% url user-profile %}"><i class="fa fa-user fa-fw"></i>{% trans "My profile" %}</a>
</li>
{% endif %}
{% if user.is_superuser %}
<li class="divider"></li>
<li><a href="{% url admin:index %}"><i class="fa fa-cogs"></i> {% trans "Admin" %}</a>
</li>
{% endif %}
<li class="divider"></li>
<li><a href="{% url logout %}"><i class="fa fa-sign-out fa-fw"></i> {% trans "Logout" %}</a>
</li>
</ul>
<!-- /.dropdown-user -->
</li>
{% else %}
<li><a href="{% url login %}">{% trans "Shibboleth Login" %}</a></li>
{% endif %}
<!-- /.dropdown -->
</ul>
<!-- /.navbar-top-links -->
</nav>
<!-- /.navbar-static-top -->
{% block sidenav %}
<nav class="navbar-default navbar-static-side" role="navigation">
{% if user.is_authenticated %}
<div class="sidebar-collapse">
<ul class="nav" id="side-menu">
<li>
<a href="{% url dashboard %}"><i class="fa fa-dashboard fa-fw"></i> {% trans "Dashboard" %}</a>
</li>
<li>
<a href="{% url group-routes %}"><i class="fa fa-shield fa-fw"></i> {% trans "Rules" %}</a>
</li>
<li>
<a href="{% url add-route %}"><i class="fa fa-plus-circle fa-fw"></i> {% trans "Add Rule" %}</a>
</li>
{% if perms.accounts.overview %}<li>
<a href="{% url overview %}"><i class="fa fa-desktop fa-fw"></i> {% trans "Overview" %}</a>
</li>{% endif %}
{% if user.is_superuser %}
<li><a href="{% url admin:index %}"><i class="fa fa-cogs fa-fw"></i> {% trans "Admin" %}</a>
</li>
{% endif %}
{% if user.get_profile.peer %}
<li>
<a href="{% url user-profile %}"><i class="fa fa-user fa-fw"></i> {% trans "My profile" %}</a>
</li>
{% endif %}
</ul>
<!-- /#side-menu -->
</div>
{% endif %}
<!-- /.sidebar-collapse -->
</nav>
<!-- /.navbar-static-side -->
{% endblock %}
<div id="page-wrapper">
{% if messages %}
<div class="row">
<div class="lg-col-12">
<div id="messages">
{% for message in messages %}
<div {% if message.tags %} class="alert alert-{{ message.tags }} alert-dismissable"{% endif %}>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
{{ message }}</span><br />
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% block contentplaceholder %}
{% endblock %}
</div>
<!-- /#page-wrapper -->
</div>
<!-- /#wrapper -->
{% block footerblock %}
{% include "footer.html" %}
{% endblock %}
<!-- Core Scripts - Include with every page -->
<script src="{{STATIC_URL}}b3theme/js/jquery-1.10.2.js"></script>
<script src="{{STATIC_URL}}js/jquery_csrf_protect.js" type="text/javascript"></script>
<script src="{{STATIC_URL}}b3theme/js/bootstrap.min.js"></script>
<script src="{{STATIC_URL}}b3theme/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script type="text/javascript" src="{{STATIC_URL}}js/jquery.cookie.js"></script>
{% block pagejs %}{% endblock %}
<!-- SB Admin Scripts - Include with every page -->
<script src="{{STATIC_URL}}b3theme/js/sb-admin.js"></script>
<!-- Page-Level Scripts - Use for reference -->
{% block pagejsbottom %}{% endblock %}
<script type="text/javascript">
function setlang(lang){
$("#langsel").val(lang);
$("#langform").submit();
}
$(document).ready(function() {
$.ajaxSetup({ cache: false });
});
</script>
</body>
</html>
This diff is collapsed.
{% extends "b3theme/base.html" %}
{% extends "base.html" %}
{% load i18n %}
{% block extrahead %}
<link href="{{STATIC_URL}}b3theme/css/plugins/morris/morris-0.4.3.min.css" rel="stylesheet">
<link href="{{STATIC_URL}}b3theme/css/plugins/timeline/timeline.css" rel="stylesheet">
<style type="text/css">
.dl-horizontal dt {
width: 70px;
}
......@@ -36,7 +36,7 @@
<ul class="timeline">
{% for route in routes %}
<li class="{% cycle '' 'timeline-inverted' %}">
{% if route.status == 'EXPIRED' or route.status == 'ADMININACTIVE' or route.status == 'INACTIVE' or route.status == 'OUTOFSYNC'%}
{% if route.status == 'EXPIRED' or route.status == 'ADMININACTIVE' or route.status == 'INACTIVE' %}
<div class="timeline-badge"><i class="fa fa-adjust"></i></div>
......@@ -61,7 +61,7 @@
<div class="timeline-panel">
<div class="timeline-heading">
<h4 class="timeline-title">{{route.name}}</h4>
<h4 class="timeline-title">{{route.name}}</h4>
<p>
<small class="text-muted"><i class="fa fa-pencil-square-o"></i> {% trans "Last update" %}: {{route.last_updated}} {% trans "by" %} {{route.applier}}</small>
</p>
......@@ -96,15 +96,15 @@
</p>
{{ route.get_match|safe|escape }}
<dl class="dl-horizontal">
<dt>Then</dt><dd>{{ route.get_then }}</dd>
</dl>
</small>
<div>
{% ifequal route.status 'ACTIVE' %}
<a href="{% url edit-route route.name %}" class="btn-info btn btn-xs btn-outline" id="edit_button_{{route.pk}}">{% trans "Edit" %}</a>
<a href="{% url edit-route route.name %}" class="btn-info btn btn-xs btn-outline" id="edit_button_{{route.pk}}">{% trans "Edit" %}</a>
<button class="del_buttonpre btn-outline btn btn-xs btn-warning" id="{{route.name}}" data-routename="{{route.name}}">{% trans "Deactivate" %}</button>
{% else %}
{% if route.status == 'EXPIRED' or route.status == 'ADMININACTIVE' or route.status == 'INACTIVE' %}
......@@ -202,7 +202,7 @@ var refreshUrl = "{% url group-routes-ajax %}";
url: delurl,
cache: false,
success: function(data) {
}
});
return false;
......@@ -219,4 +219,4 @@ var refreshUrl = "{% url group-routes-ajax %}";
</script>
{% endblock %}
\ No newline at end of file
{% endblock %}
{% extends "b3theme/base.html" %}
{% extends "base.html" %}
{% load widget_tweaks %}
{% load i18n %}
......@@ -32,7 +32,7 @@
</div>
<!-- /.col-lg-12 -->
</div>
<div class="row">
<div class="col-lg-12">
<div class="panel {% if error %}{% if inactive %}panel-primary{% else %}panel-danger{% endif %}{% endif %}">
......@@ -67,7 +67,7 @@