Merge branch 'Kerl/messages'

- Utilise une version à jour de jquery via un cdn
- Traite les messages
- Remplace les vieux simili-messages par des messages en utilisant le
  framework messages de Django
This commit is contained in:
Martin Pépin 2017-02-12 16:47:44 +01:00
commit 266a789d97
24 changed files with 189 additions and 130 deletions

View file

@ -47,11 +47,8 @@
{% for participant in participants %}{{participant.name}} : {{participant.nb_places}} places
{% endfor %}
</pre>
<script type="text/javascript"
src="{% static "js/jquery.min.js" %}"></script>
<script type="text/javascript"
src="{% static "js/joequery-Stupid-Table-Plugin/stupidtable.js" %}"></script>
<script type="text/javascript"
src="{% static "js/joequery-Stupid-Table-Plugin/stupidtable.js" %}"></script>
<script>
function toggle(id) {
var pre = document.getElementById(id) ;

View file

@ -43,9 +43,8 @@
sur {{ proposed }} place{{ proposed|pluralize }} proposée{{ proposed|pluralize }}
</span>
<script type="text/javascript"
src="{% static "js/jquery.min.js" %}"></script>
<script type="text/javascript"
src="{% static "js/joequery-Stupid-Table-Plugin/stupidtable.js" %}"></script>
src="{% static "js/joequery-Stupid-Table-Plugin/stupidtable.js" %}">
</script>
<script type="text/javascript">
$(function(){
$("table.etat-bda").stupidtable();

View file

@ -2,7 +2,6 @@
{% load staticfiles %}
{% block extra_head %}
<script src="{% static 'js/jquery.min.js'%}" type="text/javascript"></script>
<script src="{% static 'js/jquery-ui.min.js' %}" type="text/javascript"></script>
<script src="{% static "js/jquery.ui.touch-punch.min.js" %}" type="text/javascript"></script>
<link type="text/css" rel="stylesheet" href="{% static "css/jquery-ui.min.css" %}" />
@ -93,12 +92,6 @@ var django = {
</script>
<h2 class="no-bottom-margin">Inscription au tirage au sort du BdA</h2>
{% if success %}
<p class="success table-top">Votre inscription a été mise à jour avec succès !</p>
{% endif %}
{% if stateerror %}
<p class="error table-top">Impossible d'enregistrer vos modifications: vous avez apporté d'autres modifications entre temps</p>
{% endif %}
<form class="form-horizontal" id="bda_form" method="post" action="{% url 'bda-tirage-inscription' tirage.id %}">
{% csrf_token %}
{% include "bda/inscription-formset.html" %}
@ -115,7 +108,7 @@ var django = {
<input type="submit" class="btn btn-primary" value="Enregistrer" />
</div>
<p class="footnotes">
<sup>1</sup>: cette liste de v&oelig;u est ordonnée (du plus important au moins important), pour ajuster la priorité vous pouvez déplacer chaque v&oelig;u.<br />
<sup>1</sup>: cette liste de v&oelig;ux est ordonnée (du plus important au moins important), pour ajuster la priorité vous pouvez déplacer chaque v&oelig;u.<br />
</p>
</div>
</form>

View file

@ -3,15 +3,6 @@
{% block realcontent %}
<h2>Inscriptions pour BdA-Revente</h2>
{% if success %}
<p class="success">Ton inscription a bien été prise en compte !</p>
{% endif %}
{% if deja_revente %}
<p class="success">Des reventes existent déjà pour certains de ces spectacles ; vérifie les places disponibles sans tirage !</p>
{% elif inscrit_revente %}
<p class="success">Tu as été inscrit à une revente en cours pour ce spectacle !</p>
{% endif %}
<form action="" class="form-horizontal" method="post">
{% csrf_token %}
<div class="form-group">

View file

@ -1,8 +1,6 @@
{% extends "base_title.html" %}
{% block realcontent %}
<h1><strong>{{ error_title }}</strong></h1>
<p>{{ error_description }}</p>
{% if choices %}
<h3>Vos v&oelig;ux:</h3>
<ol>

View file

@ -2,9 +2,6 @@
{% block realcontent %}
<h2><strong>Places attribuées</strong></h3>
{% if warning %}
<h3 class="error">Attention, vous avez reçu plusieurs places pour des spectacles différents à la même date !</h3>
{% endif %}
{% if places %}
<table class="table table-striped">
{% for place in places %}

View file

@ -32,10 +32,9 @@
{% endfor %}
</tbody>
</table>
<script type="text/javascript"
src="{% static "js/jquery.min.js" %}"></script>
<script type="text/javascript"
src="{% static "js/joequery-Stupid-Table-Plugin/stupidtable.js" %}"></script>
<script type="text/javascript"
src="{% static "js/joequery-Stupid-Table-Plugin/stupidtable.js" %}">
</script>
<script type="text/javascript">
$(function(){
$("table.etat-bda").stupidtable();

View file

@ -10,6 +10,7 @@ from custommail.shortcuts import (
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db import models, transaction
from django.core import serializers
from django.db.models import Count, Q, Sum
@ -17,7 +18,7 @@ from django.forms.models import inlineformset_factory
from django.http import HttpResponseBadRequest, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils import timezone
from django.utils import timezone, formats
from django.views.generic.list import ListView
from gestioncof.decorators import cof_required, buro_required
@ -111,33 +112,50 @@ def places(request, tirage_id):
warning = True
else:
dates.append(date)
return render(request, "resume_places.html",
# On prévient l'utilisateur s'il a deux places à la même date
if warning:
messages.warning(request, "Attention, vous avez reçu des places pour "
"des spectacles différents à la même date.")
return render(request, "bda/resume_places.html",
{"participant": participant,
"places": filtered_places,
"tirage": tirage,
"total": total,
"warning": warning})
"total": total})
@cof_required
def inscription(request, tirage_id):
"""
Vue d'inscription à un tirage BdA.
- On vérifie qu'on se situe bien entre la date d'ouverture et la date de
fermeture des inscriptions.
- On vérifie que l'inscription n'a pas été modifiée entre le moment le
client demande le formulaire et le moment il soumet son inscription
(autre session par exemple).
"""
tirage = get_object_or_404(Tirage, id=tirage_id)
if timezone.now() < tirage.ouverture:
error_desc = tirage.ouverture.strftime('Ouverture le %d %b %Y à %H:%M')
return render(request, 'bda/resume-inscription-tirage.html',
{"error_title": "Le tirage n'est pas encore ouvert !",
"error_description": error_desc})
# Le tirage n'est pas encore ouvert.
opening = formats.localize(
timezone.template_localtime(tirage.ouverture))
messages.error(request, "Le tirage n'est pas encore ouvert : "
"ouverture le {:s}".format(opening))
return render(request, 'bda/resume-inscription-tirage.html', {})
if timezone.now() > tirage.fermeture:
# Le tirage est fermé.
participant, created = Participant.objects.get_or_create(
user=request.user, tirage=tirage)
choices = participant.choixspectacle_set.order_by("priority").all()
messages.error(request,
" C'est fini : tirage au sort dans la journée !")
return render(request, "bda/resume-inscription-tirage.html",
{"error_title": "C'est fini !",
"error_description":
"Tirage au sort dans la journée !",
"choices": choices})
{"choices": choices})
def formfield_callback(f, **kwargs):
"""
Fonction utilisée par inlineformset_factory ci dessous.
Restreint les spectacles proposés aux spectacles du bo tirage.
"""
if f.name == "spectacle":
kwargs['queryset'] = tirage.spectacle_set
return f.formfield(**kwargs)
@ -170,13 +188,19 @@ def inscription(request, tirage_id):
total_price += choice.spectacle.price
if choice.double:
total_price += choice.spectacle.price
# Messages
if success:
messages.success(request, "Votre inscription a été mise à jour avec "
"succès !")
if stateerror:
messages.error(request, "Impossible d'enregistrer vos modifications "
": vous avez apporté d'autres modifications "
"entre temps.")
return render(request, "bda/inscription-tirage.html",
{"formset": formset,
"success": success,
"total_price": total_price,
"dbstate": dbstate,
'tirage': tirage,
"stateerror": stateerror})
'tirage': tirage})
def do_tirage(tirage_elt, token):
@ -415,7 +439,7 @@ def list_revente(request, tirage_id):
user=request.user, tirage=tirage)
deja_revente = False
success = False
inscrit_revente = False
inscrit_revente = []
if request.method == 'POST':
form = InscriptionReventeForm(tirage, request.POST)
if form.is_valid():
@ -442,17 +466,29 @@ def list_revente(request, tirage_id):
if min_resell is not None:
min_resell.answered_mail.add(participant)
min_resell.save()
inscrit_revente = True
inscrit_revente.append(spectacle)
success = True
else:
form = InscriptionReventeForm(
tirage,
initial={'spectacles': participant.choicesrevente.all()})
initial={'spectacles': participant.choicesrevente.all()}
)
# Messages
if success:
messages.success(request, "Ton inscription a bien été prise en compte")
if deja_revente:
messages.info(request, "Des reventes existent déjà pour certains de "
"ces spectacles, vérifie les places "
"disponibles sans tirage !")
if inscrit_revente:
shows = map("<li>{!s}</li>".format, inscrit_revente)
msg = (
"Tu as été inscrit à des reventes en cours pour les spectacles "
"<ul>{:s}</ul>".format('\n'.join(shows))
)
messages.info(request, msg, extra_tags="safe")
return render(request, "liste-reventes.html",
{"form": form,
"deja_revente": deja_revente, "success": success,
"inscrit_revente": inscrit_revente})
return render(request, "bda/liste-reventes.html", {"form": form})
@login_required
@ -488,7 +524,7 @@ def buy_revente(request, spectacle_id):
'vendeur': revente.seller.user
}
send_custom_mail(
'bda-buy-shotgun',
'bda-buy-shotgun',
'bda@ens.fr',
[revente.seller.user.email],
context=context,

View file

@ -11,6 +11,7 @@ from django.views.generic import ListView, DetailView
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from gestioncof.models import CofProfile
from gestioncof.petits_cours_models import (
@ -101,6 +102,8 @@ def _finalize_traitement(request, demande, proposals, proposed_for,
'style="width:99%; height: 90px;">'
'</textarea>'
})
for error in errors:
messages.error(request, error)
return render(request, "gestioncof/traitement_demande_petit_cours.html",
{"demande": demande,
"unsatisfied": unsatisfied,
@ -110,7 +113,6 @@ def _finalize_traitement(request, demande, proposals, proposed_for,
"mainmail": mainmail,
"attribdata": json.dumps(attribdata),
"redo": redo,
"errors": errors,
})

View file

@ -520,22 +520,6 @@ h4.block-title {
list-style: none;
}
.success {
font-weight: bold;
color: #7AB85F;
background-color: transparent;
}
.success a {
color: inherit;
}
.error {
font-weight: bold;
color: #F6BEBE;
background-color: transparent;
}
#main form ul.errorlist li {
font-weight: bold;
color: #B00000;
@ -1092,4 +1076,46 @@ tr.awesome{
.petitcours-raw {
padding:20px;
background:#fff;
}
/* Messages */
.messages .alert .close {
top:0;
right:0;
}
.messages .alert {
padding:10px 15px;
margin:0;
border:0;
border-radius:0;
}
div.messages div.alert-info {
background-color: #659C94;
}
div.messages div.alert-success {
background-color: #41C342;
}
div.messages div.alert-warning {
background-color: #efa50f;
}
div.messages div.alert-error {
background-color: #e14b4b;
}
div.messages div.alert-info div.container,
div.messages div.alert-error div.container,
div.messages div.alert-warning div.container,
div.messages div.alert-success div.container {
color: white;
}
div.messages div.alert div.container a {
color: inherit;
}

View file

@ -4,12 +4,18 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr">
<head>
<title>{{ site.name }}</title>
<link type="text/css" rel="stylesheet" href="{% static "css/bootstrap.min.css" %}" />
<link type="text/css" rel="stylesheet" href="{% static "css/cof.css" %}" />
<link href="https://fonts.googleapis.com/css?family=Dosis|Dosis:700|Raleway|Roboto:300,300i,700" rel="stylesheet">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{# CSS #}
<link type="text/css" rel="stylesheet" href="{% static "css/bootstrap.min.css" %}" />
<link type="text/css" rel="stylesheet" href="{% static "css/cof.css" %}" />
<link href="https://fonts.googleapis.com/css?family=Dosis|Dosis:700|Raleway|Roboto:300,300i,700" rel="stylesheet">
{# JS #}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
{% block extra_head %}{% endblock %}
</head>
<body>

View file

@ -1,4 +1,4 @@
{% extends "base_header.html" %}
{% extends "gestioncof/base_header.html" %}
{% block interm_content %}
<div class="container hidden-xs espace"></div>

View file

@ -16,5 +16,21 @@
<h2 class="member-status">{% if user.first_name %}{{ user.first_name }}{% else %}<tt>{{ user.username }}</tt>{% endif %}, {% if user.profile.is_cof %}<tt class="user-is-cof">au COF{% else %}<tt class="user-is-not-cof">non-COF{% endif %}</tt></h2>
</div><!-- /.container -->
</header>
{% if messages %}
{% for message in messages %}
<div class="messages">
<div class="alert alert-{{ message.level_tag }} alert-dismissible fade in{% if message.tags %} {{ message.tags }}{% endif %}">
<div class="container">
<button class="close" data-dismiss="alert">&times;</button>
{% if 'safe' in message.tags %}
{{ message|safe }}
{% else %}
{{ message }}
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% block interm_content %}{% endblock %}
{% endblock %}

View file

@ -5,14 +5,6 @@
<h2>Calendrier dynamique</h2>
{% if success %}
<p class="success">Calendrier mis à jour avec succès</p>
{% endif %}
{% if error %}
<p class="error">{{ error }}</p>
{% endif %}
<p>Ce formulaire vous permet de définir un calendrier dynamique compatible avec
n'importe quel logiciel ou application d'agenda. Vous pouvez choisir de
souscrire aux événements du COF et/ou aux spectacles BdA.

View file

@ -2,9 +2,6 @@
{% block realcontent %}
<h2>Événement: {{ event.title }}</h2>
{% if success %}
<p class="success">Votre inscription a bien été enregistrée ! Vous pouvez cependant la modifier jusqu'à la fin des inscriptions.</p>
{% endif %}
{% if event.details %}
<p>{{ event.details }}</p>
{% endif %}

View file

@ -5,9 +5,6 @@
{% block realcontent %}
<h2>Modifier mon profil</h2>
{% if success %}
<p class="success">Votre profil a été mis à jour avec succès !</p>
{% endif %}
<form id="profile form-horizontal" method="post" action="{% url 'gestioncof.views.profile' %}">
<div class="row" style="margin: 0 15%;">
{% csrf_token %}

View file

@ -0,0 +1,8 @@
{% extends "base_title.html" %}
{% block realcontent %}
<h2>Inscription d'un nouveau membre</h2>
<div id="form-placeholder">
{% include "registration_form.html" %}
</div>
{% endblock %}

View file

@ -5,13 +5,6 @@
{% block realcontent %}
<h2>Sondage: {{ survey.title }}</h2>
{% if success %}
{% if deleted %}
<p class="success">Votre réponse a bien été supprimée !</p>
{% else %}
<p class="success">Votre réponse a bien été enregistrée ! Vous pouvez cependant la modifier jusqu'à la fin du sondage.</p>
{% endif %}
{% endif %}
{% if survey.details %}
<p>{{ survey.details }}</p>
{% endif %}

View file

@ -16,7 +16,6 @@
</ul>
</div>
{% endif %}
<script src="{% static "js/jquery.min.js" %}" type="text/javascript"></script>
{% if proposals %}
<form method="post">
{% csrf_token %}

View file

@ -1,4 +1,4 @@
{% extends "base_header.html" %}
{% extends "gestioncof/base_header.html" %}
{% block homelink %}
{% endblock %}

View file

@ -2,7 +2,6 @@
{% load staticfiles %}
{% block extra_head %}
<script src="{% static "js/jquery.min.js" %}" type="text/javascript"></script>
<script src="{% static "js/jquery-ui.min.js" %}" type="text/javascript"></script>
<script src="{% static "js/jquery.ui.touch-punch.min.js" %}" type="text/javascript"></script>
<link type="text/css" rel="stylesheet" href="{% static "css/jquery-ui.min.css" %}" />

View file

@ -4,7 +4,6 @@
{% block page_size %}col-sm-8{% endblock %}
{% block extra_head %}
<script src="{% static "js/jquery.min.js" %}" type="text/javascript"></script>
<script src="{% static "autocomplete_light/autocomplete.js" %}" type="text/javascript"></script>
{% endblock %}

View file

@ -1,12 +0,0 @@
{% extends "base_title.html" %}
{% block realcontent %}
<h2>Inscription d'un nouveau membre</h2>
{% if success %}
<p class="success">L'inscription de {{ member.first_name }} {{ member.last_name }} (<tt>{{ member.username }}</tt>) a été enregistrée avec succès.
{% if member.profile.is_cof %}Il est désormais membre du COF n°{{ member.profile.num }} !{% endif %}</p>
{% endif %}
<div id="form-placeholder">
{% include "registration_form.html" %}
</div>
{% endblock %}

View file

@ -13,6 +13,7 @@ from django.contrib.auth.views import login as django_login_view
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.utils import timezone
from django.contrib import messages
import django.utils.six as six
from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \
@ -149,10 +150,21 @@ def survey(request, survey_id):
except SurveyAnswer.DoesNotExist:
current_answer = None
form = SurveyForm(survey=survey)
return render(request, "survey.html", {"survey": survey, "form": form,
"success": success,
"deleted": deleted,
"current_answer": current_answer})
# Messages
if success:
if deleted:
messages.success(request,
"Votre réponse a bien été supprimée")
else:
messages.success(request,
"Votre réponse a bien été enregistrée ! Vous "
"pouvez cependant la modifier jusqu'à la fin "
"du sondage.")
return render(request, "gestioncof/survey.html", {
"survey": survey,
"form": form,
"current_answer": current_answer
})
def get_event_form_choices(event, form):
@ -212,8 +224,13 @@ def event(request, event_id):
current_choices=current_registration.options)
except EventRegistration.DoesNotExist:
form = EventForm(event=event)
return render(request, "event.html",
{"event": event, "form": form, "success": success})
# Messages
if success:
messages.success(request, "Votre inscription a bien été enregistrée ! "
"Vous pouvez cependant la modifier jusqu'à "
"la fin des inscriptions.")
return render(request, "gestioncof/event.html",
{"event": event, "form": form})
def clean_post_for_status(initial):
@ -300,15 +317,15 @@ def survey_status(request, survey_id):
@cof_required
def profile(request):
success = False
if request.method == "POST":
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
success = True
messages.success(request,
"Votre profil a été mis à jour avec succès !")
else:
form = UserProfileForm(instance=request.user.profile)
return render(request, "profile.html", {"form": form, "success": success})
return render(request, "gestioncof/profile.html", {"form": form})
def registration_set_ro_fields(user_form, profile_form):
@ -371,7 +388,7 @@ def registration_form2(request, login_clipper=None, username=None,
profile_form = RegistrationProfileForm()
event_formset = EventFormset(events=events, prefix='events')
clubs_form = ClubsForm()
return render(request, "registration_form.html",
return render(request, "gestioncof/registration_form.html",
{"member": member, "login_clipper": login_clipper,
"user_form": user_form,
"profile_form": profile_form,
@ -480,9 +497,17 @@ def registration(request):
club.membres.add(member)
club.save()
success = True
return render(request, "registration_post.html",
{"success": success,
"user_form": user_form,
# Messages
if success:
msg = ("L'inscription de {:s} (<tt>{:s}</tt>) a été "
"enregistrée avec succès"
.format(member.get_full_name(), member.email))
if member.profile.is_cof:
msg += "Il est désormais membre du COF n°{:d} !".format(
member.profile.num)
messages.success(request, msg, extra_tags='safe')
return render(request, "gestioncof/registration_post.html",
{"user_form": user_form,
"profile_form": profile_form,
"member": member,
"login_clipper": login_clipper,
@ -688,13 +713,15 @@ def calendar(request):
subscription.token = uuid.uuid4()
subscription.save()
form.save_m2m()
messages.success(request,
"Calendrier mis à jour avec succès.")
return render(request, "gestioncof/calendar_subscription.html",
{'form': form,
'success': True,
'token': str(subscription.token)})
else:
messages.error(request, "Formulaire incorrect.")
return render(request, "gestioncof/calendar_subscription.html",
{'form': form, 'error': "Formulaire incorrect"})
{'form': form})
else:
return render(request, "gestioncof/calendar_subscription.html",
{'form': CalendarForm(instance=instance),