--- /dev/null
+{%load alertmap%}
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+ <!-- Bootstrap CSS -->
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
+ <link rel="stylesheet" href="/media/css/font-awesome.css">
+
+ <title>postgresql.org Mail manager</title>
+ <style>
+body {
+ padding-top: 4rem;
+
+ font-weight: 400;
+ color: #515151;
+ font-size: 11.5pt;
+}
+
+.table-nonfluid {
+ width: auto !important;
+}
+ </style>
+ </head>
+ <body>
+ <div class="container-fluid">
+ <div class="row justify-content-md-center">
+ <div class="col">
+ <nav class="navbar fixed-top navbar-dark bg-dark navbar-expand-lg">
+ <a class="navbar-brand" href="/">Mail Manager</a>
+ <div class="collapse navbar-collapse" id="pgNavbar">
+ <ul class="navbar-nav">
+{%block headlinks%}{%endblock%}
+ </ul>
+ </div> <!-- pgNavBar -->
+ </nav>
+ </div> <!-- col -->
+ </div> <!-- row -->
+ <div class="row">
+ <div class="col-md-12">
+{%if messages%}
+{%for message in messages%}
+<div class="alert{% if message.tags %} {{ message.tags|alertmap }}{%endif%}">{{ message }}</div>
+{%endfor%}
+{%endif%}
+{%block content%}{%endblock%}
+ </div>
+ </div>
+ <div class="row mt-4 mb-2">
+ <div class="col-md-12">
+ <a href="/accounts/logout/" class="btn btn-secondary col-md-1 mr-3">Log out</a>
+{%if user.is_superuser %}
+ <a href="/admin/" class="btn btn-secondary col-md-1 mr-3">Django Admin</a>
+{%endif%}
+ </div>
+ </div>
+ </div> <!-- container-fluid -->
+
+ <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
+ </body>
+</html>
-<html>
-<head>
-<title>Edit</title>
-</head>
-<body>
+{%extends "base.html" %}
+{%block content%}
<h1>Edit</h1>
<form method="post" action=".">
{% csrf_token %}
-<table>
-{{form.as_table}}
-</table>
-<input type="submit" value="{{savebutton}}">
+{%if form.non_field_errors%}
+ <div class="alert alert-danger">{{form.non_field_errors}}</div>
+{%endif%}
+{%for field in form%}
+{%include "form_field.html"%}
+{%endfor%}
+
+ <div class="form-group">
+ <div class="col-lg-12">
+ <div class="control">
+ <input type="submit" name="submit" class="col-md-2 mb-2 mr-2 btn btn-primary" value="{{savebutton|default:"Save"}}">
+{%if cancelurl%}
+ <a class="col-md-2 mb-2 mr-2 btn btn-secondary" href="{{cancelurl}}">{{cancelname|default:"Cancel"}}</a>
+{%endif%}
+ </div>
+ </div>
+ </div>
+
</form>
-</body>
-</html>
+{%endblock%}
--- /dev/null
+{%load formutil%}
+{%if not field.is_hidden%}
+<div class="form-group">
+ {{field|label_class:""}}
+ {%if field.errors %}
+ {%for e in field.errors%}
+ <div class="alert alert-danger">{{e}}</div>
+ {%endfor%}
+ {%endif%}
+{{field|field_class:"form-control"}}
+{%if field.help_text%}<small class="form-text text-muted">{{field.help_text|safe}}</small>{%endif%}
+ </div>
+ {%else%}{# field.is_hidden #}
+{{field}}
+ {%endif%}
-<html>
-<head>
- <title>Mail manager</title>
-</head>
-<body>
- <h1>Mail manager</h1>
+{%extends "base.html" %}
+{%block headlinks%}
+<li class="nav-item p-2"><a href="/#users" title="Users">Users</a></li>
+<li class="nav-item p-2"><a href="/#forwarders" title="Forwarders">Forwarders</a></li>
+{%endblock%}
-{%if messages%}
-<ul class="messages">
- {% for message in messages %}
- <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
- {% endfor %}
-</ul>
-{%endif%}
+{%block content%}
- <h2>Users</h2>
-<table border="1" cellspacing="0" cellpadding="1">
-<tr>
- <th>Local part</th>
- <th>Domain</th>
- <th>Full name</th>
-</tr>
+<a name="users"></a>
+<h2>Users</h2>
+<table class="table table-striped table-hover table-sm table-nonfluid">
+<thead>
+ <tr>
+ <th>Local part</th>
+ <th>Domain</th>
+ <th>Full name</th>
+ </tr>
+</thead>
+<tbody>
{%for u in users%}
<tr>
<td><a href="/user/{{u.pk}}/">{{u.local_part}}</a></td>
<td>{{u.full_name|default:''}}</td>
</tr>
{%endfor%}
+</tbody>
</table>
-<a href="/user/add/">Add</a> new.
+<a href="/user/add/" class="btn btn-primary">Add new user</a>
-<h2>Forwardings</h2>
-<table border="1" cellspacing="0" cellpadding="1">
+<a name="forwarders"></a>
+<h2 class="mt-4">Forwarders</h2>
+<table class="table table-striped table-hover table-sm table-nonfluid">
+<thead>
<tr>
<th>Local part</th>
<th>Domain</th>
<th>Remote name</th>
</tr>
+</thead>
+<tbody>
{%for f in forwarders%}
<tr>
<td><a href="/forwarder/{{f.pk}}/">{{f.local_part}}</a></td>
<td>{{f.remote_name}}</td>
</tr>
{%endfor%}
+</tbody>
</table>
-<a href="/forwarder/add/">Add</a> new.
+<a href="/forwarder/add/" class="btn btn-primary">Add new forwarder</a>
-<br/>
-<br/>
-<a href="/accounts/logout/">Log out</a><br/>
-{% if user.is_superuser %}
-<a href="/admin/">View admin</a><br/>
-{%endif%}
-</body>
-</html>
+{%endblock%}
--- /dev/null
+from django.template.defaultfilters import stringfilter
+from django import template
+
+register = template.Library()
+
+
+@stringfilter
+def alertmap(value):
+ if value == 'error':
+ return 'alert-danger'
+ elif value == 'warning':
+ return 'alert-warning'
+ elif value == 'success':
+ return 'alert-success'
+ else:
+ return 'alert-info'
--- /dev/null
+from django import template
+
+register = template.Library()
+
+
+def label_class(value, arg):
+ return value.label_tag(attrs={'class': arg})
+
+
+def field_class(value, arg):
+ prevclass = value.field.widget.attrs.get('class', '')
+ if prevclass:
+ newclass = "{0} {1}".format(arg, prevclass)
+ else:
+ newclass = arg
+ return value.as_widget(attrs={"class": newclass})
return render(request, 'form.html', {
'form': form,
- 'savebutton': (userparam == 'new') and "New" or "Save"
+ 'savebutton': (userparam == 'new') and "New" or "Save",
+ 'cancelurl': '/',
})
return render(request, 'form.html', {
'form': form,
- 'savebutton': (userparam == 'new') and "New" or "Save"
+ 'savebutton': (userparam == 'new') and "New" or "Save",
+ 'cancelurl': '/#forwarders',
})