Make the layout slightly less sucky
authorMagnus Hagander <[email protected]>
Sun, 24 Feb 2019 12:02:58 +0000 (13:02 +0100)
committerMagnus Hagander <[email protected]>
Sun, 24 Feb 2019 12:02:58 +0000 (13:02 +0100)
pgmailmgr/mailmgr/templates/base.html [new file with mode: 0644]
pgmailmgr/mailmgr/templates/form.html
pgmailmgr/mailmgr/templates/form_field.html [new file with mode: 0644]
pgmailmgr/mailmgr/templates/home.html
pgmailmgr/mailmgr/templatetags/__init__.py [new file with mode: 0644]
pgmailmgr/mailmgr/templatetags/alertmap.py [new file with mode: 0644]
pgmailmgr/mailmgr/templatetags/formutil.py [new file with mode: 0644]
pgmailmgr/mailmgr/views.py

diff --git a/pgmailmgr/mailmgr/templates/base.html b/pgmailmgr/mailmgr/templates/base.html
new file mode 100644 (file)
index 0000000..1690833
--- /dev/null
@@ -0,0 +1,64 @@
+{%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>
index 35f9c9567636bbbb6ab871b301125a421094368c..a58a91cea4bf91cbf20252250fc7648050bda1c1 100644 (file)
@@ -1,16 +1,26 @@
-<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%}
diff --git a/pgmailmgr/mailmgr/templates/form_field.html b/pgmailmgr/mailmgr/templates/form_field.html
new file mode 100644 (file)
index 0000000..381df21
--- /dev/null
@@ -0,0 +1,15 @@
+{%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%}
index 492b91d1b79d63fb6bd3c6c4779260a96e5d1fa4..27eb32ededea3748b0294dc18eb723445fb1611c 100644 (file)
@@ -1,25 +1,22 @@
-<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%}
diff --git a/pgmailmgr/mailmgr/templatetags/__init__.py b/pgmailmgr/mailmgr/templatetags/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pgmailmgr/mailmgr/templatetags/alertmap.py b/pgmailmgr/mailmgr/templatetags/alertmap.py
new file mode 100644 (file)
index 0000000..c1cd5fd
--- /dev/null
@@ -0,0 +1,17 @@
+from django.template.defaultfilters import stringfilter
+from django import template
+
+register = template.Library()
+
+
[email protected](name='alertmap')
+@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'
diff --git a/pgmailmgr/mailmgr/templatetags/formutil.py b/pgmailmgr/mailmgr/templatetags/formutil.py
new file mode 100644 (file)
index 0000000..3f2a02f
--- /dev/null
@@ -0,0 +1,18 @@
+from django import template
+
+register = template.Library()
+
+
[email protected](is_safe=True)
+def label_class(value, arg):
+    return value.label_tag(attrs={'class': arg})
+
+
[email protected](is_safe=True)
+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})
index 5497fb94e33ae8db2837344e1e329985ab4bb076..3171339081bd3053c8f2f2b1b2b518ab876a9c4c 100644 (file)
@@ -59,7 +59,8 @@ def userform(request, userparam):
 
     return render(request, 'form.html', {
         'form': form,
-        'savebutton': (userparam == 'new') and "New" or "Save"
+        'savebutton': (userparam == 'new') and "New" or "Save",
+        'cancelurl': '/',
     })
 
 
@@ -87,5 +88,6 @@ def forwarderform(request, userparam):
 
     return render(request, 'form.html', {
         'form': form,
-        'savebutton': (userparam == 'new') and "New" or "Save"
+        'savebutton': (userparam == 'new') and "New" or "Save",
+        'cancelurl': '/#forwarders',
     })