Browse Source

Merge branch 'master' of git.illyse.org:coin

Conflicts:
	coin/vpn/templates/vpn/vpn.html
illysedev 10 years ago
parent
commit
a0c3fff276

+ 5 - 4
coin/billing/admin.py

@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django import forms
 from django.contrib import admin
 from django.contrib import messages
 from django.http import HttpResponseRedirect
@@ -11,7 +10,7 @@ from django.contrib.admin.util import flatten_fieldsets
 from coin.filtering_queryset import LimitedAdminInlineMixin
 from coin.billing.models import Invoice, InvoiceDetail, Payment
 from coin.billing.utils import get_invoice_from_id_or_number
-from coin.offers.models import OfferSubscription
+from django.core.urlresolvers import reverse
 import autocomplete_light
 
 
@@ -142,7 +141,7 @@ class InvoiceAdmin(admin.ModelAdmin):
 
     def validate_view(self, request, id):
         """
-        Vue appelée lorsque l'admin souhaite valider une facture et 
+        Vue appelée lorsque l'admin souhaite valider une facture et
         générer son pdf
         """
         # TODO : Add better perm here
@@ -155,6 +154,8 @@ class InvoiceAdmin(admin.ModelAdmin):
                 request, 'Vous n\'avez pas l\'autorisation de valider '
                          'une facture.')
 
-        return HttpResponseRedirect(request.META["HTTP_REFERER"])
+        return HttpResponseRedirect(reverse('admin:billing_invoice_change',
+                                            args=(id,)))
+
 
 admin.site.register(Invoice, InvoiceAdmin)

+ 8 - 6
coin/members/admin.py

@@ -8,8 +8,8 @@ from django.contrib.auth.admin import UserAdmin
 from django.contrib.auth.models import Group
 from django.http import HttpResponseRedirect
 from django.conf.urls import url
-from django.contrib import messages
 from django.db.models.query import QuerySet
+from django.core.urlresolvers import reverse
 
 from coin.members.models import Member, CryptoKey, LdapUser, MembershipFee
 from coin.members.membershipfee_filter import MembershipFeeFilter
@@ -116,9 +116,9 @@ class MemberAdmin(UserAdmin):
         ]
         return my_urls + urls
 
-    def send_welcome_email(self, request, id):
+    def send_welcome_email(self, request, id, return_httpredirect=True):
         """
-        Vue appelée lorsque l'admin souhaite envoyer l'email de bienvenue à un 
+        Vue appelée lorsque l'admin souhaite envoyer l'email de bienvenue à un
         membre.
         """
         # TODO : Add better perm here
@@ -132,15 +132,17 @@ class MemberAdmin(UserAdmin):
                 request, 'Vous n\'avez pas l\'autorisation d\'envoyer des '
                          'courriels de bienvenue.')
 
-        return HttpResponseRedirect(request.META["HTTP_REFERER"])
+        if return_httpredirect:
+            return HttpResponseRedirect(reverse('admin:members_member_changelist'))
+
 
     def bulk_send_welcome_email(self, request, queryset):
         """
-        Action appelée lorsque l'admin souhaite envoyer un lot d'email de bienvenue 
+        Action appelée lorsque l'admin souhaite envoyer un lot d'email de bienvenue
         depuis une sélection de membre dans la vue liste de l'admin
         """
         for member in queryset.all():
-            self.send_welcome_email(request, member.id)
+            self.send_welcome_email(request, member.id, return_httpredirect=False)
         messages.success(request,
                          'Le courriel de bienvenue a été envoyé à %d membre(s).' % queryset.count())
     bulk_send_welcome_email.short_description = "Envoyer le courriel de bienvenue"

+ 12 - 2
coin/members/templates/members/registration/password_reset_form.html

@@ -11,14 +11,14 @@
 <div class="row">
     <div class="large-12 columns">
         <h2>Réinitialiser son mot de passe</h2>
-        <p>Nouvel adhérent ? Mot de passe perdu ?<br/>Saisissez l'adresse email de votre compte afin de reçevoir les instruction pour en définir un nouveau.</p>
+        <p>Nouvel adhérent ? Mot de passe perdu ?<br/>Saisissez l'adresse email de votre compte afin de reçevoir les instructions pour en définir un nouveau.</p>
 
         {% if form.errors %}
         <div class="alert-box alert">
             {% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
         </div>
         {% endif %}
-    
+
         <form action="" method="post">{% csrf_token %}
             <label {% if form.id_email.errors %}class="error"{% endif %}>{% trans 'Email address' %}
                 {{ form.email }}
@@ -32,3 +32,13 @@
     </div>
 </div>
 {% endblock %}
+
+{% block js %}
+    <script>
+        $(function(){
+            //On récupère l'email passé éventuellement en paramètre GET.
+            email = $.urlParam('email');
+            if (email) $('#id_email').val(decodeURIComponent(email));
+        });
+    </script>
+{% endblock %}

+ 1 - 1
coin/mixins.py

@@ -39,7 +39,7 @@ class CoinLdapSyncMixin(object):
         # Si la sauvegarde LDAP échoue, Rollback la sauvegarde en base, sinon
         # commit
         try:
-            self.sync_to_ldap(creation=creation,update_fields=update_fields)
+            self.sync_to_ldap(creation=creation, update_fields=update_fields)
         except:
             raise
 

+ 2 - 2
coin/static/css/illyse.css

@@ -201,7 +201,7 @@ span.italic {
     font-weight: bold;
 }
 
-h3.graphtitle select {
+#graph h3 select {
 	display: inline;
 	background-color: transparent;
 	border: 0 none transparent;
@@ -212,7 +212,7 @@ h3.graphtitle select {
 	margin: 0;
 	padding: 0;
 }
-h3.graphtitle select option {
+#graph h3 select option {
 	font-size: 0.6em;
 }
 

+ 13 - 46
coin/static/js/illyse.js

@@ -1,46 +1,13 @@
-window.onload = function() {
-	var field = document.getElementById("passgen");
-	if (field != undefined) field.onclick = function() {
-		if (!confirm("Ceci va effacer votre ancien mot de passe et en générer un nouveau. Continuer ?")) return false;
-		var cell = field.parentNode;
-		cell.removeChild(field);
-		cell.appendChild(document.createElement("img"));
-		cell.lastChild.src = "/static/img/coin.ajax.gif";
-		cell.appendChild(document.createTextNode(" Génération en cours…"));
-		var xhr = new XMLHttpRequest();
-		xhr.onreadystatechange = function() {
-			if (xhr.readyState != 4) return;
-			var table = cell.parentNode.parentNode;
-			if (xhr.responseXML == null)
-				var pass = (new DOMParser().parseFromString(xhr.responseText, "text/html")).getElementById("password");
-			else var pass = xhr.responseXML.getElementById("password");
-			table.insertBefore(pass.cloneNode(true), cell.parentNode);
-			do pass = pass.nextSibling; while (pass.nodeType == 3);
-			table.insertBefore(pass.cloneNode(true), cell.parentNode);
-			table.removeChild(cell.parentNode);
-		};
-		xhr.open("GET", field.href, false);
-		xhr.send(null);
-		return false;
-	};
-	
-	var field = document.getElementById("trafic_zoom");
-	if (field != undefined) {
-		var select = document.createElement("select");
-		var options = {"hourly": "une heure", "daily": "24 heures", "weekly": "7 jours", "monthly": "un mois", "yearly": "un an"};
-		for (var i in options) {
-			var opt = document.createElement("option");
-			opt.appendChild(document.createTextNode(options[i]));
-			opt.value = i;
-			select.appendChild(opt);
-		}
-		select.childNodes[1].selected = "selected";
-		var graph = document.getElementById("trafic_graph");
-		var href = graph.src+"/";
-		select.onchange = function() {
-			graph.src = href+select.value;
-		};
-		field.parentNode.insertBefore(select, field);
-		field.parentNode.removeChild(field);
-	}
-};
+$(function() {
+    // Make URL parameters accessibles everywere by $.urlParam('my_param')
+    $.urlParam = function(name){
+        var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
+        if (results==null){
+           return null;
+        }
+        else{
+           return results[1] || 0;
+        }
+    }
+
+});

+ 3 - 3
coin/templates/base.html

@@ -10,7 +10,6 @@
     <link rel="stylesheet" href="{% static "css/illyse.css" %}" />
     <link rel="stylesheet" href="{% static "css/offcanvas.css" %}">
     <script src="{% static "js/vendor/modernizr.js" %}"></script>
-    <script src="{% static "js/illyse.js" %}"></script>
     <link rel="icon" type="image/png" href="{% static "img/coinitem.png" %}"/>
     <link rel="icon" type="image/x-icon" href="{% static "img/favicon.ico" %}" />
 </head>
@@ -20,7 +19,7 @@
     <header>
        <h1><a href="{% url 'home' %}">COIN est un Outil pour un Internet Neutre</a></h1>
     </header>
-    
+
     {% if user.is_authenticated %}
     <div class="show-for-small">
         <a class="left-off-canvas-toggle button">Menu</a>
@@ -45,7 +44,7 @@
             {% endblock %}
         </div>
         {% endif %}
-        
+
         <div class="large-{% if user.is_authenticated %}9{% else %}12{% endif %} columns">
             {% block content %}{% endblock %}
         </div>
@@ -65,6 +64,7 @@
     <script src="{% static "js/vendor/jquery.js" %}"></script>
     <script src="{% static "js/foundation.min.js" %}"></script>
     <script src="{% static "js/foundation/foundation.offcanvas.js" %}"></script>
+    <script src="{% static "js/illyse.js" %}"></script>
     {% block js %}{% endblock %}
 
     <script>

+ 8 - 0
coin/vpn/templates/vpn/fragments/password.html

@@ -0,0 +1,8 @@
+<tr id="password">
+    <td class="center"><span class="label">Mot de passe</span></td>
+    <td><span class="pass">{{ password }}</span></td>
+</tr>
+<tr>
+    <td class="warning" colspan="2">Ce mot de passe ne sera affiché qu'une seule fois. Si vous le perdez, il faudra en générer un nouveau.</td>
+</tr>
+

+ 0 - 11
coin/vpn/templates/vpn/password.html

@@ -1,11 +0,0 @@
-{% extends "vpn/vpn.html" %}
-
-{% block password %}
-                <tr id="password">
-                    <td class="center"><span class="label">Mot de passe</span></td>
-                    <td><span class="pass">{{ password }}</span></td>
-                </tr>
-                <tr>
-                    <td class="warning" colspan="2">Ce mot de passe ne sera affiché qu'une seule fois. Si vous le perdez, il faudra en générer un nouveau.</td>
-                </tr>
-{% endblock %}

+ 49 - 8
coin/vpn/templates/vpn/vpn.html

@@ -11,14 +11,14 @@
         {{ message }}
     </div>
     {% endfor %}
-    
+
     {% if form.non_field_errors or form.ipv4_endpoint.errors or form.ipv6_endpoint.errors %}
     <div class="alert-box alert nogap">
       {{ form.non_field_errors }}
       {{ form.ipv4_endpoint.errors }}
       {{ form.ipv6_endpoint.errors }}
     </div>{% endif %}
-    
+
     <div class="large-6 columns">
         <div class="panel">
             <h3>Statut</h3>
@@ -26,14 +26,14 @@
                 <tr>
                     <td class="center"><span class="label">Identifiant</span></td>
                     <td>{{object.login}}</td>
-                </tr>{% block password %}
+                </tr>
                 <tr>
                     <td class="center" colspan="2">
-                        <a class="button radius tiny" id="passgen" href="{% url 'vpn:generate_password' object.pk %}"><i class="fa fa-refresh"></i>
+                        <a class="button tiny radius" id="passgen" href="{% url 'vpn:generate_password' object.pk %}"><i class="fa fa-refresh"></i>
  Générer un nouveau mot de passe</a>
                     </td>
                 </tr>
-                {% endblock %}<tr class="flatfield">
+                <tr class="flatfield">
                     <td class="center">{{ form.comment.label_tag }}</td>
                     <td>{{ form.comment }}</td>
                 </tr>
@@ -72,9 +72,50 @@
     </form>
 </div>
 
-<div class="row">
-    <h3 class="graphtitle">Graphe de trafic sur <span id="trafic_zoom">24 heures</span> :</h3>
-    <img id="trafic_graph" src="{% url 'vpn:get_graph' vpn_id=object.pk %}" alt="Graphe de trafic {{ object.login }}" />
+<div class="row" id="graph">
+    <h3>Graphe de trafic sur
+        <select id="graph_period">
+            <option value="hourly">une heure</option>
+            <option value="daily" selected>24 heures</option>
+            <option value="weekly">7 jours</option>
+            <option value="monthly">un mois</option>
+            <option value="yearly">un an</option>
+        </select> : <small class="pending_request"></small></h3>
+    <img id="graph_trafic" src="{% url 'vpn:get_graph' vpn_id=object.pk %}" alt="Graphe de trafic {{ object.login }}" />
 </div>
 
 {% endblock %}
+
+{% block js %}
+    <script>
+        // Bouton génération du mot de passe
+        $('#passgen').click(function(){
+            if (!confirm("Ceci va effacer votre ancien mot de passe et en générer un nouveau. Continuer ?")) return false;
+
+            parent_cell = $(this).parent();
+            parent_cell.html('<span class="pending_request"><i class="fa fa-refresh fa-spin"></i> Génération en cours</span>');
+
+            $.ajax({
+                'url': $(this).attr('href')
+            }).done(function(html) {
+                //Remplace le tr parent par le contenu renvoyé (qui est deux tr successifs)
+                parent_cell.parent().replaceWith(html);
+            }).fail(function( jqXHR, textStatus ) {
+                parent_cell.html('<span class="error">Échec de la requête : ' + textStatus + '</span>');
+            });
+
+            return false;
+        });
+
+        // Graphe de conso data
+        $('#graph_period').change(function(){
+            $('#graph .pending_request').html('<i class="fa fa-refresh fa-spin"></i>');
+            base_url = "{% url 'vpn:get_graph' vpn_id=object.pk %}/";
+            $('#graph_trafic').attr('src', base_url + $(this).val());
+        });
+        $('#graph_trafic').load(function() {
+            $('#graph .pending_request').html('');
+        });
+
+    </script>
+{% endblock js %}

+ 1 - 1
coin/vpn/urls.py

@@ -9,7 +9,7 @@ urlpatterns = patterns(
     # This is part of the generic configuration interface (the "name" is
     # the same as the "backend_name" of the model).
     url(r'^(?P<id>\d+)$', VPNView.as_view(template_name="vpn/vpn.html"), name="details"),
-    url(r'^password/(?P<id>\d+)$', VPNGeneratePasswordView.as_view(template_name="vpn/password.html"), name="generate_password"),
+    url(r'^password/(?P<id>\d+)$', VPNGeneratePasswordView.as_view(template_name="vpn/fragments/password.html"), name="generate_password"),
     url(r'^graph/(?P<vpn_id>[0-9]+)/(?P<period>[a-z]+)$', get_graph, name="get_graph"),
     url(r'^graph/(?P<vpn_id>[0-9]+)$', get_graph, name="get_graph"),
 )

+ 2 - 2
coin/vpn/views.py

@@ -42,7 +42,7 @@ def generate_password(request, id):
     # This will hash the password automatically
     vpn.full_clean()
     vpn.save()
-    return render_to_response('vpn/password.html', {"vpn": vpn,
+    return render_to_response('vpn/fragments/password.html', {"vpn": vpn,
                                                     "password": password})
 
 
@@ -68,7 +68,7 @@ def get_graph(request, vpn_id, period="daily"):
     """
     vpn = get_object_or_404(VPNConfiguration, pk=vpn_id,
                             offersubscription__member=request.user)
-    
+
     time_periods = { 'hourly': '-1hour', 'daily': '-24hours', 'weekly': '-8days', 'monthly': '-32days', 'yearly': '-13months', }
     if period not in time_periods:
         period = 'daily'