Merge branch 'thubrecht/faq' into 'master'
Création de l'application de faq See merge request klub-dev-ens/kadenios!6
This commit is contained in:
commit
191144c234
17 changed files with 560 additions and 113 deletions
0
faqs/__init__.py
Normal file
0
faqs/__init__.py
Normal file
28
faqs/forms.py
Normal file
28
faqs/forms.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from translated_fields import language_code_formfield_callback
|
||||
|
||||
from django import forms
|
||||
|
||||
from .models import Faq
|
||||
|
||||
|
||||
class FaqForm(forms.ModelForm):
|
||||
formfield_callback = language_code_formfield_callback
|
||||
|
||||
class Meta:
|
||||
model = Faq
|
||||
fields = [
|
||||
*Faq.title.fields,
|
||||
"anchor",
|
||||
*Faq.description.fields,
|
||||
*Faq.content.fields,
|
||||
]
|
||||
widgets = {
|
||||
"description_en": forms.Textarea(
|
||||
attrs={"rows": 4, "class": "is-family-monospace"}
|
||||
),
|
||||
"description_fr": forms.Textarea(
|
||||
attrs={"rows": 4, "class": "is-family-monospace"}
|
||||
),
|
||||
"content_en": forms.Textarea(attrs={"class": "is-family-monospace"}),
|
||||
"content_fr": forms.Textarea(attrs={"class": "is-family-monospace"}),
|
||||
}
|
66
faqs/migrations/0001_initial.py
Normal file
66
faqs/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Generated by Django 3.2.4 on 2021-06-15 08:34
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Faq",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("title_fr", models.CharField(max_length=255, verbose_name="titre")),
|
||||
(
|
||||
"title_en",
|
||||
models.CharField(blank=True, max_length=255, verbose_name="titre"),
|
||||
),
|
||||
("description_fr", models.TextField(verbose_name="description")),
|
||||
(
|
||||
"description_en",
|
||||
models.TextField(blank=True, verbose_name="description"),
|
||||
),
|
||||
("content_fr", models.TextField(blank=True, verbose_name="contenu")),
|
||||
("content_en", models.TextField(blank=True, verbose_name="contenu")),
|
||||
(
|
||||
"last_modified",
|
||||
models.DateField(auto_now=True, verbose_name="mise à jour"),
|
||||
),
|
||||
("anchor", models.CharField(max_length=20, verbose_name="ancre")),
|
||||
(
|
||||
"author",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="faqs",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"permissions": [("is_author", "Can create faqs")],
|
||||
},
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name="faq",
|
||||
constraint=models.UniqueConstraint(
|
||||
fields=("anchor",), name="unique_faq_anchor"
|
||||
),
|
||||
),
|
||||
]
|
0
faqs/migrations/__init__.py
Normal file
0
faqs/migrations/__init__.py
Normal file
14
faqs/mixins.py
Normal file
14
faqs/mixins.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
|
||||
|
||||
class AdminOnlyMixin(PermissionRequiredMixin):
|
||||
"""Restreint l'accès aux admins"""
|
||||
|
||||
permission_required = "faqs.is_author"
|
||||
|
||||
|
||||
class CreatorOnlyMixin(AdminOnlyMixin):
|
||||
"""Restreint l'accès à l'auteur"""
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(author=self.request.user)
|
32
faqs/models.py
Normal file
32
faqs/models.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
from translated_fields import TranslatedFieldWithFallback
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Faq(models.Model):
|
||||
title = TranslatedFieldWithFallback(
|
||||
models.CharField(_("titre"), blank=False, max_length=255)
|
||||
)
|
||||
description = TranslatedFieldWithFallback(
|
||||
models.TextField(_("description"), blank=False)
|
||||
)
|
||||
content = TranslatedFieldWithFallback(models.TextField(_("contenu"), blank=True))
|
||||
|
||||
author = models.ForeignKey(
|
||||
User, related_name="faqs", null=True, on_delete=models.SET_NULL
|
||||
)
|
||||
last_modified = models.DateField(_("mise à jour"), auto_now=True)
|
||||
|
||||
anchor = models.CharField(_("ancre"), max_length=20)
|
||||
|
||||
class Meta:
|
||||
permissions = [
|
||||
("is_author", "Can create faqs"),
|
||||
]
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=["anchor"], name="unique_faq_anchor")
|
||||
]
|
43
faqs/templates/faqs/faq.html
Normal file
43
faqs/templates/faqs/faq.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n markdown %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="level">
|
||||
{# Titre de la FAQ #}
|
||||
<div class="level-left is-flex-shrink-1">
|
||||
<h1 class="title">{{ faq.title }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="level-right">
|
||||
{# Date de dernière modification #}
|
||||
<div class="level-item">
|
||||
<span class="tag is-primary is-light is-outlined">{% blocktrans with maj=faq.last_modified|date:'d/m/Y' %}Mis à jour le {{ maj }}{% endblocktrans %}</span>
|
||||
</div>
|
||||
|
||||
{# Lien vers la page d'édition #}
|
||||
{% if faq.author == user %}
|
||||
<div class="level-item">
|
||||
<a class="button has-tooltip-primary" href="{% url 'faq.edit' faq.anchor %}" data-tooltip="{% trans "Modifier" %}">
|
||||
<span class="icon">
|
||||
<i class="fas fa-cog"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
{# Description #}
|
||||
<div class="message is-primary">
|
||||
<div class="message-body content">{{ faq.description|markdown|safe }}</div>
|
||||
</div>
|
||||
|
||||
{# Contenu #}
|
||||
<div class="content">
|
||||
{{ faq.content|markdown|safe }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
20
faqs/templates/faqs/faq_create.html
Normal file
20
faqs/templates/faqs/faq_create.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% for error in form.non_field_errors %}
|
||||
<div class="notification is-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<h1 class="title">{% trans "Nouvelle FAQ" %}</h1>
|
||||
<hr>
|
||||
|
||||
{% url 'faq.list' as r_url %}
|
||||
{% include "forms/common-form.html" with c_size="is-9" errors=False %}
|
||||
|
||||
{% endblock %}
|
||||
|
20
faqs/templates/faqs/faq_edit.html
Normal file
20
faqs/templates/faqs/faq_edit.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% for error in form.non_field_errors %}
|
||||
<div class="notification is-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<h1 class="title">{% trans "Modification de la FAQ" %}</h1>
|
||||
<hr>
|
||||
|
||||
{% url 'faq.view' faq.anchor as r_url %}
|
||||
{% include "forms/common-form.html" with c_size="is-9" errors=False %}
|
||||
|
||||
{% endblock %}
|
||||
|
48
faqs/templates/faqs/faq_list.html
Normal file
48
faqs/templates/faqs/faq_list.html
Normal file
|
@ -0,0 +1,48 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n markdown %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<h1 class="title">{% trans "Liste des FAQ" %}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if perms.faqs.is_author %}
|
||||
<div class="level-right">
|
||||
<div class="level-item">
|
||||
<a class="button is-light is-outlined is-primary" href={% url 'faq.create' %}>
|
||||
<span class="icon">
|
||||
<i class="fas fa-plus"></i>
|
||||
</span>
|
||||
<span>{% trans "Créer une FAQ" %}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
{% for f in faq_list %}
|
||||
<div class="panel is-primary is-radiusless">
|
||||
<div class="panel-heading is-size-6 is-radiusless">
|
||||
<a class="has-text-primary-light" href="{% url 'faq.view' f.anchor %}"><u>{{ f.title }}</u></a>
|
||||
</div>
|
||||
|
||||
{% if f.description %}
|
||||
<div class="panel-block">
|
||||
<div class="content is-flex-grow-1">
|
||||
{{ f.description|markdown|safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if not forloop.last %}
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
12
faqs/urls.py
Normal file
12
faqs/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
# Admin views
|
||||
path("create", views.FaqCreateView.as_view(), name="faq.create"),
|
||||
path("edit/<slug:slug>", views.FaqEditView.as_view(), name="faq.edit"),
|
||||
# Public views
|
||||
path("", views.FaqListView.as_view(), name="faq.list"),
|
||||
path("view/<slug:slug>", views.FaqView.as_view(), name="faq.view"),
|
||||
]
|
54
faqs/views.py
Normal file
54
faqs/views.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import CreateView, DetailView, ListView, UpdateView
|
||||
|
||||
from .forms import FaqForm
|
||||
from .mixins import AdminOnlyMixin, CreatorOnlyMixin
|
||||
from .models import Faq
|
||||
|
||||
# #############################################################################
|
||||
# Administration Views
|
||||
# #############################################################################
|
||||
|
||||
|
||||
class FaqCreateView(AdminOnlyMixin, SuccessMessageMixin, CreateView):
|
||||
model = Faq
|
||||
form_class = FaqForm
|
||||
success_message = _("Faq créée avec succès !")
|
||||
template_name = "faqs/faq_create.html"
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse("faq.view", args=[self.object.anchor])
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.author = self.request.user
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class FaqEditView(CreatorOnlyMixin, SuccessMessageMixin, UpdateView):
|
||||
model = Faq
|
||||
form_class = FaqForm
|
||||
slug_field = "anchor"
|
||||
success_message = _("Faq modifiée avec succès !")
|
||||
template_name = "faqs/faq_edit.html"
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse("faq.view", args=[self.object.anchor])
|
||||
|
||||
|
||||
# #############################################################################
|
||||
# Public Views
|
||||
# #############################################################################
|
||||
|
||||
|
||||
class FaqListView(ListView):
|
||||
model = Faq
|
||||
template_name = "faqs/faq_list.html"
|
||||
|
||||
|
||||
class FaqView(DetailView):
|
||||
model = Faq
|
||||
template_name = "faqs/faq.html"
|
||||
slug_field = "anchor"
|
|
@ -55,6 +55,7 @@ INSTALLED_APPS = [
|
|||
"kadenios.apps.IgnoreSrcStaticFilesConfig",
|
||||
"shared",
|
||||
"elections",
|
||||
"faqs",
|
||||
"authens",
|
||||
]
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ urlpatterns = [
|
|||
path("", HomeView.as_view(), name="kadenios"),
|
||||
path("admin/", admin.site.urls),
|
||||
path("elections/", include("elections.urls")),
|
||||
path("faqs/", include("faqs.urls")),
|
||||
path("auth/", include("shared.auth.urls")),
|
||||
path("authens/", include("authens.urls")),
|
||||
path("i18n/", include("django.conf.urls.i18n")),
|
||||
|
|
Binary file not shown.
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-05-28 10:58+0200\n"
|
||||
"PO-Revision-Date: 2021-05-28 10:59+0200\n"
|
||||
"POT-Creation-Date: 2021-06-18 19:34+0200\n"
|
||||
"PO-Revision-Date: 2021-06-18 21:19+0200\n"
|
||||
"Last-Translator: Test Translator <test@translator>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: en\n"
|
||||
|
@ -16,7 +16,7 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.4.3\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
|
||||
#: elections/forms.py:19
|
||||
msgid "Impossible de faire débuter l'élection dans le passé"
|
||||
|
@ -31,20 +31,22 @@ msgid ""
|
|||
"Le mail d'annonce a déjà été envoyé, il n'est pas possible d'ouvrir "
|
||||
"l'élection à tout le monde"
|
||||
msgstr ""
|
||||
"The announcement email has already been sent, it is not possible to open the "
|
||||
"election to everyone"
|
||||
|
||||
#: elections/forms.py:55
|
||||
#: elections/forms.py:63
|
||||
msgid "Sélectionnez un fichier .csv"
|
||||
msgstr "Select a .csv file"
|
||||
|
||||
#: elections/forms.py:65
|
||||
#: elections/forms.py:73
|
||||
msgid "Extension de fichier invalide, il faut un fichier au format CSV."
|
||||
msgstr "Invalid file extension, a CSV file is required."
|
||||
|
||||
#: elections/forms.py:72
|
||||
#: elections/forms.py:80
|
||||
msgid "Objet"
|
||||
msgstr "Subject"
|
||||
|
||||
#: elections/forms.py:94
|
||||
#: elections/forms.py:102
|
||||
msgid ""
|
||||
"L'abréviation est optionnelle et sert à identifier plus facilement les "
|
||||
"différentes options. Elle est affiché sans espaces et en majuscules."
|
||||
|
@ -52,116 +54,120 @@ msgstr ""
|
|||
"The abbreviation is optional and serves to identify the different options "
|
||||
"more easily. It is displayed without spaces and in capital letters."
|
||||
|
||||
#: elections/forms.py:105
|
||||
#: elections/forms.py:113
|
||||
msgid "Supprimer le vote de {} ({}) ?"
|
||||
msgstr "Delete the vote of {} ({}) ?"
|
||||
|
||||
#: elections/forms.py:110 elections/templates/elections/election_admin.html:191
|
||||
#: elections/templates/elections/election_admin.html:218
|
||||
#: elections/forms.py:118 elections/templates/elections/election_admin.html:243
|
||||
#: elections/templates/elections/election_admin.html:270
|
||||
#: elections/templates/elections/election_voters.html:82
|
||||
msgid "Supprimer"
|
||||
msgstr "Delete"
|
||||
|
||||
#: elections/forms.py:110
|
||||
#: elections/forms.py:118
|
||||
msgid "Non"
|
||||
msgstr "No"
|
||||
|
||||
#: elections/forms.py:110
|
||||
#: elections/forms.py:118
|
||||
msgid "Oui"
|
||||
msgstr "Yes"
|
||||
|
||||
#: elections/models.py:31
|
||||
#: elections/models.py:33
|
||||
msgid "nom"
|
||||
msgstr "name"
|
||||
|
||||
#: elections/models.py:32
|
||||
#: elections/models.py:34
|
||||
msgid "nom bref"
|
||||
msgstr "short name"
|
||||
|
||||
#: elections/models.py:34
|
||||
#: elections/models.py:36 faqs/models.py:15
|
||||
msgid "description"
|
||||
msgstr "description"
|
||||
|
||||
#: elections/models.py:37
|
||||
#: elections/models.py:39
|
||||
msgid "date et heure de début"
|
||||
msgstr "start date and time"
|
||||
|
||||
#: elections/models.py:38
|
||||
#: elections/models.py:40
|
||||
msgid "date et heure de fin"
|
||||
msgstr "end date and time"
|
||||
|
||||
#: elections/models.py:41
|
||||
#: elections/models.py:42
|
||||
msgid "visible au public"
|
||||
msgstr "visible to everyone"
|
||||
|
||||
#: elections/models.py:45
|
||||
msgid "conditions de vote"
|
||||
msgstr "voting requirements"
|
||||
|
||||
#: elections/models.py:45
|
||||
#: elections/models.py:49
|
||||
msgid "restreint le vote à une liste de personnes"
|
||||
msgstr "restricts the vote to a list of people"
|
||||
|
||||
#: elections/models.py:49
|
||||
#: elections/models.py:53
|
||||
msgid "mail avec les identifiants envoyé"
|
||||
msgstr "mail with credentials sent"
|
||||
|
||||
#: elections/models.py:66
|
||||
#: elections/models.py:70
|
||||
msgid "résultats publics"
|
||||
msgstr "results published"
|
||||
|
||||
#: elections/models.py:67
|
||||
#: elections/models.py:71
|
||||
msgid "dépouillée"
|
||||
msgstr "counted"
|
||||
|
||||
#: elections/models.py:69
|
||||
#: elections/models.py:73
|
||||
msgid "archivée"
|
||||
msgstr "archived"
|
||||
|
||||
#: elections/models.py:79
|
||||
#: elections/models.py:77
|
||||
msgid "Peut administrer des élections"
|
||||
msgstr "Can manage elections"
|
||||
|
||||
#: elections/models.py:87
|
||||
msgid "question"
|
||||
msgstr "question"
|
||||
|
||||
#: elections/models.py:81
|
||||
#: elections/models.py:90
|
||||
msgid "type de question"
|
||||
msgstr "type of question"
|
||||
|
||||
#: elections/models.py:88
|
||||
#: elections/models.py:97
|
||||
msgid "nombre maximal de votes reçus"
|
||||
msgstr "maximal number of votes received"
|
||||
|
||||
#: elections/models.py:139
|
||||
#: elections/models.py:154
|
||||
msgid "texte"
|
||||
msgstr "text"
|
||||
|
||||
#: elections/models.py:140
|
||||
#: elections/models.py:155
|
||||
msgid "abréviation"
|
||||
msgstr "abbreviation"
|
||||
|
||||
#: elections/models.py:142
|
||||
#: elections/models.py:157
|
||||
msgid "option gagnante"
|
||||
msgstr "winning option"
|
||||
|
||||
#: elections/models.py:150
|
||||
#: elections/models.py:165
|
||||
msgid "nombre de votes reçus"
|
||||
msgstr "number of votes received"
|
||||
|
||||
#: elections/models.py:177
|
||||
#: elections/models.py:192
|
||||
msgid "rang de l'option"
|
||||
msgstr "option's ranking"
|
||||
|
||||
#: elections/models.py:193
|
||||
#: elections/models.py:208
|
||||
msgid "votes supplémentaires"
|
||||
msgstr "extra votes"
|
||||
|
||||
#: elections/models.py:209
|
||||
#: elections/models.py:224
|
||||
msgid "Nom et Prénom"
|
||||
msgstr "Name and surname"
|
||||
|
||||
#: elections/models.py:232 elections/tests/test_models.py:57
|
||||
#: elections/models.py:247 elections/tests/test_models.py:57
|
||||
msgid "identifiants spécifiques"
|
||||
msgstr "dedicated credentials"
|
||||
|
||||
#: elections/models.py:236
|
||||
msgid "Peut administrer des élections"
|
||||
msgstr "Can manage elections"
|
||||
|
||||
#: elections/staticdefs.py:26 elections/tests/test_models.py:56
|
||||
msgid "mot de passe"
|
||||
msgstr "password"
|
||||
|
@ -235,7 +241,7 @@ msgid "Élection en cours"
|
|||
msgstr "Election in progress"
|
||||
|
||||
#: elections/templates/elections/election.html:52
|
||||
#: elections/templates/elections/election_list.html:72
|
||||
#: elections/templates/elections/election_list.html:83
|
||||
msgid "Administrer"
|
||||
msgstr "Manage"
|
||||
|
||||
|
@ -280,70 +286,92 @@ msgstr "Login with credentials"
|
|||
msgid "Connexion via CAS"
|
||||
msgstr "Login via CAS"
|
||||
|
||||
#: elections/templates/elections/election.html:189
|
||||
#: elections/templates/elections/election.html:194
|
||||
msgid "A voté"
|
||||
msgstr "Voted"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:21
|
||||
#: elections/templates/elections/election_admin.html:282
|
||||
#: elections/templates/elections/election_admin.html:291
|
||||
msgid "Rajouter une question"
|
||||
msgstr "Add a question"
|
||||
#: elections/templates/elections/election_admin.html:51
|
||||
#: elections/templates/elections/election_list.html:58
|
||||
msgid "Élection invisible"
|
||||
msgstr "Invisible election"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:21
|
||||
msgid "Modifier la question"
|
||||
msgstr "Change the question"
|
||||
#: elections/templates/elections/election_admin.html:58
|
||||
msgid "Élection visible"
|
||||
msgstr "Visible election"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:26
|
||||
#: elections/templates/elections/election_admin.html:267
|
||||
#: elections/templates/elections/election_admin.html:278
|
||||
msgid "Rajouter une option"
|
||||
msgstr "Add an option"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:26
|
||||
msgid "Modifier l'option"
|
||||
msgstr "Change the option"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:53
|
||||
#: elections/templates/elections/election_admin.html:72
|
||||
msgid "Actions"
|
||||
msgstr "Actions"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:65
|
||||
#: elections/templates/elections/election_admin.html:84
|
||||
msgid "Vue classique"
|
||||
msgstr "Classic view"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:95
|
||||
msgid "Rendre l'élection visible"
|
||||
msgstr "Make the election visible"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:104
|
||||
msgid "Exporter les votant·e·s"
|
||||
msgstr "Export the list of voters"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:74
|
||||
#: elections/templates/elections/election_admin.html:200
|
||||
#: elections/templates/elections/election_admin.html:224
|
||||
#: elections/templates/elections/election_admin.html:113
|
||||
#: elections/templates/elections/election_admin.html:252
|
||||
#: elections/templates/elections/election_admin.html:276
|
||||
#: faqs/templates/faqs/faq.html:22
|
||||
msgid "Modifier"
|
||||
msgstr "Edit"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:83
|
||||
#: elections/templates/elections/election_admin.html:122
|
||||
#: elections/templates/elections/upload_voters.html:27
|
||||
msgid "Gestion de la liste de votant·e·s"
|
||||
msgstr "Management of the voters' list"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:95
|
||||
#: elections/templates/elections/election_admin.html:134
|
||||
#: elections/templates/elections/election_voters.html:48
|
||||
msgid "Liste des votant·e·s"
|
||||
msgstr "Voters' list"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:103
|
||||
#: elections/templates/elections/election_admin.html:142
|
||||
msgid "Dépouiller"
|
||||
msgstr "Count"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:115
|
||||
#: elections/templates/elections/election_admin.html:154
|
||||
msgid "Publier"
|
||||
msgstr "Publish"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:117
|
||||
#: elections/templates/elections/election_admin.html:156
|
||||
msgid "Dépublier"
|
||||
msgstr "De-publish"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:128
|
||||
#: elections/templates/elections/election_admin.html:166
|
||||
msgid "Télécharger les résultats"
|
||||
msgstr "Download the results"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:175
|
||||
msgid "Archiver"
|
||||
msgstr "Archive"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:247
|
||||
msgid "Modifier la question"
|
||||
msgstr "Change the question"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:276
|
||||
msgid "Modifier l'option"
|
||||
msgstr "Change the option"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:315
|
||||
#: elections/templates/elections/election_admin.html:319
|
||||
#: elections/templates/elections/election_admin.html:330
|
||||
msgid "Rajouter une option"
|
||||
msgstr "Add an option"
|
||||
|
||||
#: elections/templates/elections/election_admin.html:334
|
||||
#: elections/templates/elections/election_admin.html:339
|
||||
#: elections/templates/elections/election_admin.html:343
|
||||
msgid "Rajouter une question"
|
||||
msgstr "Add a question"
|
||||
|
||||
#: elections/templates/elections/election_ballots.html:18
|
||||
#: elections/templates/elections/election_voters.html:40
|
||||
#: elections/templates/elections/upload_voters.html:48
|
||||
|
@ -359,7 +387,7 @@ msgstr "Back"
|
|||
msgid "Liste des bulletins"
|
||||
msgstr "List of ballots"
|
||||
|
||||
#: elections/templates/elections/election_create.html:31
|
||||
#: elections/templates/elections/election_create.html:32
|
||||
msgid "Création d'une élection"
|
||||
msgstr "Creating an election"
|
||||
|
||||
|
@ -371,19 +399,19 @@ msgstr "List of elections"
|
|||
msgid "Créer une élection"
|
||||
msgstr "Create an election"
|
||||
|
||||
#: elections/templates/elections/election_list.html:54
|
||||
#: elections/templates/elections/election_list.html:65
|
||||
msgid "Élection dépouillée"
|
||||
msgstr "Election counted"
|
||||
|
||||
#: elections/templates/elections/election_list.html:60
|
||||
#: elections/templates/elections/election_list.html:71
|
||||
msgid "Élection publiée"
|
||||
msgstr "Published election"
|
||||
|
||||
#: elections/templates/elections/election_list.html:66
|
||||
#: elections/templates/elections/election_list.html:77
|
||||
msgid "Élection archivée"
|
||||
msgstr "Archived election"
|
||||
|
||||
#: elections/templates/elections/election_update.html:31
|
||||
#: elections/templates/elections/election_update.html:32
|
||||
msgid "Modification d'une élection"
|
||||
msgstr "Editing an election"
|
||||
|
||||
|
@ -519,50 +547,50 @@ msgstr "Confirm"
|
|||
msgid "Annuler"
|
||||
msgstr "Cancel"
|
||||
|
||||
#: elections/templates/elections/vote/rank.html:150
|
||||
#: elections/templates/elections/vote/rank.html:154
|
||||
msgid "Classement"
|
||||
msgstr "Ranking"
|
||||
|
||||
#: elections/templates/elections/vote/rank.html:151
|
||||
#: elections/templates/elections/vote/rank.html:155
|
||||
#: elections/templates/elections/vote/select.html:24
|
||||
msgid "Option(s) selectionnée(s)"
|
||||
msgstr "Selected option(s)"
|
||||
|
||||
#: elections/templates/elections/vote/rank.html:171
|
||||
#: elections/templates/elections/vote/rank.html:224
|
||||
#: elections/templates/elections/vote/rank.html:175
|
||||
#: elections/templates/elections/vote/rank.html:228
|
||||
msgid "Utiliser le formulaire classique"
|
||||
msgstr "Use the traditional form"
|
||||
|
||||
#: elections/templates/elections/vote/rank.html:176
|
||||
#: elections/templates/elections/vote/rank.html:180
|
||||
msgid "Utiliser le cliquer-déposer"
|
||||
msgstr "Use Drag & Drop"
|
||||
|
||||
#: elections/templates/elections/vote/rank.html:234
|
||||
#: elections/templates/elections/vote/rank.html:238
|
||||
#, python-format
|
||||
msgid "Rang %(i)s"
|
||||
msgstr "Rank %(i)s"
|
||||
|
||||
#: elections/templates/elections/vote/rank.html:245
|
||||
#: elections/templates/elections/vote/rank.html:249
|
||||
msgid "Ajouter un rang"
|
||||
msgstr "Add an rank"
|
||||
|
||||
#: elections/utils.py:207
|
||||
#: elections/utils.py:195
|
||||
msgid "Vous devez sélectionnner une option."
|
||||
msgstr "You must select an option."
|
||||
|
||||
#: elections/utils.py:212
|
||||
#: elections/utils.py:200
|
||||
msgid "Vous ne pouvez pas sélectionner plus d'une option."
|
||||
msgstr "You cannot select more than one option."
|
||||
|
||||
#: elections/utils.py:229
|
||||
#: elections/utils.py:217
|
||||
msgid "Le classement maximal est {}."
|
||||
msgstr "The maximum ranking is {}."
|
||||
|
||||
#: elections/utils.py:233
|
||||
#: elections/utils.py:221
|
||||
msgid "Le classement minimal est 1."
|
||||
msgstr "The minimum ranking is 1."
|
||||
|
||||
#: elections/utils.py:347
|
||||
#: elections/utils.py:335
|
||||
msgid ""
|
||||
"Format invalide. Vérifiez que le fichier est bien formé (i.e. chaque ligne "
|
||||
"de la forme 'login,nom,email')."
|
||||
|
@ -570,83 +598,132 @@ msgstr ""
|
|||
"Invalid format. Check that the file is properly formed (i.e. each line of "
|
||||
"the form 'login,name,e-mail')."
|
||||
|
||||
#: elections/utils.py:361
|
||||
#: elections/utils.py:349
|
||||
msgid "La ligne {} n'a pas le bon nombre d'éléments."
|
||||
msgstr "The line {} has the wrong number of elements."
|
||||
|
||||
#: elections/utils.py:366
|
||||
#: elections/utils.py:354
|
||||
msgid "Valeur manquante dans la ligne {} : 'login'."
|
||||
msgstr "Missing value in line {}: 'login'."
|
||||
|
||||
#: elections/utils.py:371
|
||||
#: elections/utils.py:359
|
||||
msgid "Doublon dans les logins : lignes {} et {}."
|
||||
msgstr "Duplicate logins: lines {} and {}."
|
||||
|
||||
#: elections/utils.py:379
|
||||
#: elections/utils.py:367
|
||||
msgid "Valeur manquante dans la ligne {} : 'nom'."
|
||||
msgstr "Missing value in line {}: 'name'."
|
||||
|
||||
#: elections/utils.py:385
|
||||
#: elections/utils.py:373
|
||||
msgid "Adresse mail invalide à la ligne {} : '{}'."
|
||||
msgstr "Invalid e-mail address in line {}: '{}'."
|
||||
|
||||
#: elections/views.py:73
|
||||
#: elections/views.py:58
|
||||
msgid "Élection créée avec succès !"
|
||||
msgstr "Election successfully created!"
|
||||
|
||||
#: elections/views.py:130
|
||||
#: elections/views.py:99
|
||||
msgid "Élection visible !"
|
||||
msgstr "Election now visible!"
|
||||
|
||||
#: elections/views.py:127
|
||||
msgid "Liste de votant·e·s importée avec succès !"
|
||||
msgstr "Voters list successfully imported!"
|
||||
|
||||
#: elections/views.py:164
|
||||
#: elections/views.py:161
|
||||
msgid "Mail d'annonce envoyé avec succès !"
|
||||
msgstr "Announcement e-mail sent successfully!"
|
||||
|
||||
#: elections/views.py:196
|
||||
#: elections/views.py:193
|
||||
msgid "Élection modifiée avec succès !"
|
||||
msgstr "Election successfully modified!"
|
||||
|
||||
#: elections/views.py:279
|
||||
#: elections/views.py:276
|
||||
msgid "Élection dépouillée avec succès !"
|
||||
msgstr "Election successfully counted!"
|
||||
|
||||
#: elections/views.py:305
|
||||
#: elections/views.py:302
|
||||
msgid "Élection publiée avec succès !"
|
||||
msgstr "Election successfully published!"
|
||||
|
||||
#: elections/views.py:306
|
||||
#: elections/views.py:303
|
||||
msgid "Élection dépubliée avec succès !"
|
||||
msgstr "Election successfully de-published!"
|
||||
|
||||
#: elections/views.py:318
|
||||
#: elections/views.py:330
|
||||
msgid "Élection archivée avec succès !"
|
||||
msgstr "Election successfully archived!"
|
||||
|
||||
#: elections/views.py:350
|
||||
#: elections/views.py:362
|
||||
msgid "Question modifiée avec succès !"
|
||||
msgstr "Question successfully modified!"
|
||||
|
||||
#: elections/views.py:362
|
||||
#: elections/views.py:374
|
||||
msgid "Question supprimée !"
|
||||
msgstr "Question deleted!"
|
||||
|
||||
#: elections/views.py:400
|
||||
#: elections/views.py:412
|
||||
msgid "Option modifiée avec succès !"
|
||||
msgstr "Option successfully modified!"
|
||||
|
||||
#: elections/views.py:412
|
||||
#: elections/views.py:424
|
||||
msgid "Option supprimée !"
|
||||
msgstr "Option deleted!"
|
||||
|
||||
#: elections/views.py:566
|
||||
#: elections/views.py:578
|
||||
msgid "Votre choix a bien été enregistré !"
|
||||
msgstr "Your choice has been recorded!"
|
||||
|
||||
#: kadenios/settings/common.py:138
|
||||
#: faqs/models.py:12
|
||||
msgid "titre"
|
||||
msgstr "title"
|
||||
|
||||
#: faqs/models.py:17
|
||||
msgid "contenu"
|
||||
msgstr "content"
|
||||
|
||||
#: faqs/models.py:22
|
||||
msgid "mise à jour"
|
||||
msgstr "updated"
|
||||
|
||||
#: faqs/models.py:24
|
||||
msgid "ancre"
|
||||
msgstr "anchor"
|
||||
|
||||
#: faqs/templates/faqs/faq.html:16
|
||||
#, python-format
|
||||
msgid "Mis à jour le %(maj)s"
|
||||
msgstr "Updated on %(maj)s"
|
||||
|
||||
#: faqs/templates/faqs/faq_create.html:13
|
||||
msgid "Nouvelle FAQ"
|
||||
msgstr "New FAQ"
|
||||
|
||||
#: faqs/templates/faqs/faq_edit.html:13
|
||||
msgid "Modification de la FAQ"
|
||||
msgstr "Editing an FAQ"
|
||||
|
||||
#: faqs/templates/faqs/faq_list.html:10
|
||||
msgid "Liste des FAQ"
|
||||
msgstr "List of FAQs"
|
||||
|
||||
#: faqs/templates/faqs/faq_list.html:21
|
||||
msgid "Créer une FAQ"
|
||||
msgstr "Create a FAQ"
|
||||
|
||||
#: faqs/views.py:18
|
||||
msgid "Faq créée avec succès !"
|
||||
msgstr "FAQ successfully created!"
|
||||
|
||||
#: faqs/views.py:34
|
||||
msgid "Faq modifiée avec succès !"
|
||||
msgstr "FAQ successfully modified!"
|
||||
|
||||
#: kadenios/settings/common.py:140
|
||||
msgid "Français"
|
||||
msgstr "French"
|
||||
|
||||
#: kadenios/settings/common.py:139
|
||||
#: kadenios/settings/common.py:141
|
||||
msgid "Anglais"
|
||||
msgstr "English"
|
||||
|
||||
|
@ -698,20 +775,43 @@ msgstr "Password reset"
|
|||
msgid "Envoyer un mail"
|
||||
msgstr "Send an e-mail"
|
||||
|
||||
#: shared/templates/base.html:124
|
||||
#: shared/templates/authens/pwd_reset_email.txt:2
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Quelqu'un (probablement vous) a demandé la réinitialisation du mot de passe "
|
||||
"associé à cette addresse sur %(site_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: shared/templates/authens/pwd_reset_email.txt:4
|
||||
msgid ""
|
||||
"S'il s'agit bien de vous, vous pouvez vous rendre à l'adresse suivante pour "
|
||||
"en choisir un nouveau : "
|
||||
msgstr ""
|
||||
|
||||
#: shared/templates/authens/pwd_reset_email.txt:8
|
||||
#, python-format
|
||||
msgid "Pour information, votre nom d'utilisateur est le suivant : %(username)s"
|
||||
msgstr ""
|
||||
|
||||
#: shared/templates/authens/pwd_reset_email.txt:10
|
||||
#, python-format
|
||||
msgid "L'équipe %(site_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: shared/templates/base.html:122
|
||||
msgid "Élections"
|
||||
msgstr "Elections"
|
||||
|
||||
#: shared/templates/base.html:136
|
||||
#: shared/templates/base.html:143
|
||||
#, python-format
|
||||
msgid "Connecté·e en tant que %(name)s par %(connection)s"
|
||||
msgstr "Logged in as %(name)s via %(connection)s"
|
||||
|
||||
#: shared/templates/base.html:152
|
||||
#: shared/templates/base.html:159
|
||||
msgid "Se connecter"
|
||||
msgstr "Log in"
|
||||
|
||||
#: shared/templates/base.html:235
|
||||
#: shared/templates/base.html:242
|
||||
msgid ""
|
||||
"Développé par <a class=\"tag is-light is-danger\" href=\"https://www.eleves."
|
||||
"ens.fr/kde\">KDEns</a>. En cas de pépin, contacter <span class=\"tag is-info "
|
||||
|
|
|
@ -112,16 +112,24 @@
|
|||
<nav class="level has-background-primary">
|
||||
<div class="level-left px-4">
|
||||
<div class="level-item">
|
||||
<a href="{% url "kadenios" %}">
|
||||
<a href="{% url 'kadenios' %}">
|
||||
<h1 class="has-text-primary-light is-size-1 is-family-secondary">Kadenios</h1>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="level-item px-4">
|
||||
<a href="{% url "election.list" %}">
|
||||
<div class="level-item pl-4">
|
||||
<a href="{% url 'election.list' %}">
|
||||
<h3 class="has-text-primary-light has-text-weight-semibold is-size-3">{% trans "Élections" %}</h3>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% comment %}
|
||||
<div class="level-item pl-4">
|
||||
<a href="{% url 'faq.list' %}">
|
||||
<h3 class="has-text-primary-light has-text-weight-semibold is-size-3">{% trans "FAQ" %}</h3>
|
||||
</a>
|
||||
</div>
|
||||
{% endcomment %}
|
||||
</div>
|
||||
|
||||
<div class="level-right px-5">
|
||||
|
|
Loading…
Reference in a new issue