mirror of
https://github.com/ae-utbm/sith.git
synced 2025-10-09 08:14:39 +00:00
Split ClubMemberForm into JoinClubForm and ClubAddMemberForm
This commit is contained in:
@@ -208,15 +208,14 @@ class ClubOldMemberForm(forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class ClubMemberForm(forms.ModelForm):
|
class ClubMemberForm(forms.ModelForm):
|
||||||
"""Form handling the members of a club."""
|
"""Form to add a member to the club, as a board member."""
|
||||||
|
|
||||||
error_css_class = "error"
|
error_css_class = "error"
|
||||||
required_css_class = "required"
|
required_css_class = "required"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Membership
|
model = Membership
|
||||||
fields = ["user", "role", "description"]
|
fields = ["role", "description"]
|
||||||
widgets = {"user": AutoCompleteSelectUser}
|
|
||||||
|
|
||||||
def __init__(self, *args, club: Club, request_user: User, **kwargs):
|
def __init__(self, *args, club: Club, request_user: User, **kwargs):
|
||||||
self.club = club
|
self.club = club
|
||||||
@@ -231,22 +230,36 @@ class ClubMemberForm(forms.ModelForm):
|
|||||||
]
|
]
|
||||||
self.instance.club = club
|
self.instance.club = club
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_available_role(self): # pragma: no cover
|
||||||
|
"""The greatest role that will be obtainable with this form."""
|
||||||
|
# this is unreachable, because it will be overridden by subclasses
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
class ClubAddMemberForm(ClubMemberForm):
|
||||||
|
"""Form to add a member to the club, as a board member."""
|
||||||
|
|
||||||
|
class Meta(ClubMemberForm.Meta):
|
||||||
|
fields = ["user", *ClubMemberForm.Meta.fields]
|
||||||
|
widgets = {"user": AutoCompleteSelectUser}
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def max_available_role(self):
|
def max_available_role(self):
|
||||||
"""The greatest role that will be obtainable with this form.
|
"""The greatest role that will be obtainable with this form.
|
||||||
|
|
||||||
Admins and the club president can attribute any role.
|
Admins and the club president can attribute any role.
|
||||||
Board members can attribute roles lower than their own.
|
Board members can attribute roles lower than their own.
|
||||||
Other users can attribute curious and member roles.
|
Other users cannot attribute roles with this form
|
||||||
"""
|
"""
|
||||||
if self.request_user.has_perm("club.add_subscription"):
|
if self.request_user.has_perm("club.add_subscription"):
|
||||||
return settings.SITH_CLUB_ROLES_ID["President"]
|
return settings.SITH_CLUB_ROLES_ID["President"]
|
||||||
membership = self.request_user_membership
|
membership = self.request_user_membership
|
||||||
if membership is not None and membership.role > settings.SITH_MAXIMUM_FREE_ROLE:
|
if membership is None or membership.role <= settings.SITH_MAXIMUM_FREE_ROLE:
|
||||||
if membership.role == settings.SITH_CLUB_ROLES_ID["President"]:
|
return -1
|
||||||
return membership.role
|
if membership.role == settings.SITH_CLUB_ROLES_ID["President"]:
|
||||||
return membership.role - 1
|
return membership.role
|
||||||
return settings.SITH_MAXIMUM_FREE_ROLE
|
return membership.role - 1
|
||||||
|
|
||||||
def clean_user(self):
|
def clean_user(self):
|
||||||
"""Check that the user is not trying to add a user already in the club.
|
"""Check that the user is not trying to add a user already in the club.
|
||||||
@@ -264,18 +277,26 @@ class ClubMemberForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
class JoinClubForm(ClubMemberForm):
|
||||||
|
"""Form to join a club."""
|
||||||
|
|
||||||
|
def __init__(self, *args, club: Club, request_user: User, **kwargs):
|
||||||
|
super().__init__(*args, club=club, request_user=request_user, **kwargs)
|
||||||
|
self.instance.user = self.request_user
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def max_available_role(self):
|
||||||
|
return settings.SITH_MAXIMUM_FREE_ROLE
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
"""Check user rights for adding a user."""
|
"""Check that the user is subscribed and isn't already in the club."""
|
||||||
cleaned_data = super().clean()
|
if not self.request_user.is_subscribed:
|
||||||
if (
|
|
||||||
self.request_user_membership is None
|
|
||||||
or self.request_user_membership.role <= settings.SITH_MAXIMUM_FREE_ROLE
|
|
||||||
) and not self.request_user.has_perm("club.add_membership"):
|
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_(
|
_("You must be subscribed to join a club"), code="invalid"
|
||||||
"You cannot add other users to a club "
|
|
||||||
"if you are not in the club board."
|
|
||||||
),
|
|
||||||
code="invalid",
|
|
||||||
)
|
)
|
||||||
return cleaned_data
|
if self.club.get_membership_for(self.request_user):
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("You are already a member of this club"), code="invalid"
|
||||||
|
)
|
||||||
|
return super().clean()
|
||||||
|
@@ -6,23 +6,22 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block additional_css %}
|
{% block additional_css %}
|
||||||
<link rel="stylesheet" href="{{ static("bundled/core/components/ajax-select-index.css") }}">
|
<link rel="stylesheet" href="{{ static("bundled/core/components/ajax-select-index.css") }}">
|
||||||
<link rel="stylesheet" href="{{ static("core/components/ajax-select.scss") }}">
|
|
||||||
<link rel="stylesheet" href="{{ static("club/members.scss") }}">
|
<link rel="stylesheet" href="{{ static("club/members.scss") }}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% block notifications %}
|
{% block notifications %}
|
||||||
{# Notifications are moved inside the billing info fragment #}
|
{# Notifications are moved a little bit below #}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<h2>{% trans %}Club members{% endtrans %}</h2>
|
<h2>{% trans %}Club members{% endtrans %}</h2>
|
||||||
|
|
||||||
{% if add_member_fragment %}
|
{% if add_member_fragment %}
|
||||||
<br />
|
<br />
|
||||||
<h4>{% trans %}Add a new member{% endtrans %}</h4>
|
|
||||||
{{ add_member_fragment }}
|
{{ add_member_fragment }}
|
||||||
<br />
|
<br />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% include "core/base/notifications.jinja" %}
|
||||||
{% if members %}
|
{% if members %}
|
||||||
<form action="{{ url('club:club_members', club_id=club.id) }}" id="members_old" method="post">
|
<form action="{{ url('club:club_members', club_id=club.id) }}" id="members_old" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
@@ -1,32 +1,46 @@
|
|||||||
|
<section id="member-fragment-container">
|
||||||
|
{% if form.user %}
|
||||||
|
<h4>{% trans %}Add a new member{% endtrans %}</h4>
|
||||||
|
{% else %}
|
||||||
|
<h4>{% trans %}Join club{% endtrans %}</h4>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% include "core/base/notifications.jinja" %}
|
<form
|
||||||
|
hx-post="{{ url('club:club_new_members', club_id=club.id) }}"
|
||||||
<form
|
hx-disabled-elt="find input[type='submit']"
|
||||||
hx-post="{{ url('club:club_new_members', club_id=club.id) }}"
|
hx-swap="outerHTML"
|
||||||
hx-disabled-elt="find input[type='submit']"
|
hx-target="#member-fragment-container"
|
||||||
hx-swap="outerHTML"
|
id="add_club_members_form"
|
||||||
id="add_club_members_form"
|
>
|
||||||
>
|
{% csrf_token %}
|
||||||
{% csrf_token %}
|
{{ form.non_field_errors() }}
|
||||||
{{ form.non_field_errors() }}
|
<fieldset>
|
||||||
<fieldset>
|
{% if form.user %}
|
||||||
<div>
|
<div>
|
||||||
{{ form.user.label_tag()}}
|
{{ form.user.label_tag() }}
|
||||||
<span class="helptext">{{ form.user.help_text }}</span>
|
<span class="helptext">{{ form.user.help_text }}</span>
|
||||||
{{ form.user }}
|
{{ form.user }}
|
||||||
{{ form.user.errors }}
|
{{ form.user.errors }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
{% endif %}
|
||||||
{{ form.role.label_tag()}}
|
<div>
|
||||||
{{ form.role }}
|
{{ form.role.label_tag() }}
|
||||||
{{ form.role.errors }}
|
{{ form.role }}
|
||||||
</div>
|
{{ form.role.errors }}
|
||||||
<div>
|
</div>
|
||||||
{{ form.description.label_tag()}}
|
<div>
|
||||||
{{ form.description }}
|
{{ form.description.label_tag() }}
|
||||||
{{ form.description.errors }}
|
{{ form.description }}
|
||||||
</div>
|
{{ form.description.errors }}
|
||||||
</fieldset>
|
</div>
|
||||||
<button type="submit" class="btn btn-blue">
|
</fieldset>
|
||||||
<i class="fa fa-user-plus"></i> {% trans %}Add{% endtrans %}</button>
|
<button type="submit" class="btn btn-blue">
|
||||||
</form>
|
<i class="fa fa-user-plus"></i>
|
||||||
|
{%- if club.user -%}
|
||||||
|
{% trans %}Add{% endtrans %}
|
||||||
|
{%- else -%}
|
||||||
|
{% trans %}Join{% endtrans %}
|
||||||
|
{%- endif -%}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
|
from collections.abc import Callable
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
import pytest
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
@@ -11,7 +13,7 @@ from django.utils.timezone import localdate, localtime, now
|
|||||||
from model_bakery import baker
|
from model_bakery import baker
|
||||||
from pytest_django.asserts import assertRedirects
|
from pytest_django.asserts import assertRedirects
|
||||||
|
|
||||||
from club.forms import ClubMemberForm
|
from club.forms import ClubAddMemberForm, JoinClubForm
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
from club.tests.base import TestClub
|
from club.tests.base import TestClub
|
||||||
from core.baker_recipes import subscriber_user
|
from core.baker_recipes import subscriber_user
|
||||||
@@ -268,7 +270,7 @@ class TestMembership(TestClub):
|
|||||||
cannot be members of clubs.
|
cannot be members of clubs.
|
||||||
"""
|
"""
|
||||||
for user in self.public, self.old_subscriber:
|
for user in self.public, self.old_subscriber:
|
||||||
form = ClubMemberForm(
|
form = ClubAddMemberForm(
|
||||||
data={"user": user.id, "role": 1},
|
data={"user": user.id, "role": 1},
|
||||||
request_user=self.root,
|
request_user=self.root,
|
||||||
club=self.club,
|
club=self.club,
|
||||||
@@ -308,7 +310,7 @@ class TestMembership(TestClub):
|
|||||||
nb_memberships = self.club.members.count()
|
nb_memberships = self.club.members.count()
|
||||||
max_id = User.objects.aggregate(id=Max("id"))["id"]
|
max_id = User.objects.aggregate(id=Max("id"))["id"]
|
||||||
for members in [max_id + 1], [max_id + 1, self.subscriber.id]:
|
for members in [max_id + 1], [max_id + 1, self.subscriber.id]:
|
||||||
form = ClubMemberForm(
|
form = ClubAddMemberForm(
|
||||||
data={"user": members, "role": 1},
|
data={"user": members, "role": 1},
|
||||||
request_user=self.root,
|
request_user=self.root,
|
||||||
club=self.club,
|
club=self.club,
|
||||||
@@ -346,7 +348,7 @@ class TestMembership(TestClub):
|
|||||||
"""Test that a member of the club member cannot create
|
"""Test that a member of the club member cannot create
|
||||||
a membership with a greater role than its own.
|
a membership with a greater role than its own.
|
||||||
"""
|
"""
|
||||||
form = ClubMemberForm(
|
form = ClubAddMemberForm(
|
||||||
data={"user": self.subscriber.id, "role": 10},
|
data={"user": self.subscriber.id, "role": 10},
|
||||||
request_user=self.simple_board_member,
|
request_user=self.simple_board_member,
|
||||||
club=self.club,
|
club=self.club,
|
||||||
@@ -363,7 +365,7 @@ class TestMembership(TestClub):
|
|||||||
|
|
||||||
def test_add_member_without_role(self):
|
def test_add_member_without_role(self):
|
||||||
"""Test that trying to add members without specifying their role fails."""
|
"""Test that trying to add members without specifying their role fails."""
|
||||||
form = ClubMemberForm(
|
form = ClubAddMemberForm(
|
||||||
data={"user": self.subscriber.id}, request_user=self.root, club=self.club
|
data={"user": self.subscriber.id}, request_user=self.root, club=self.club
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -371,7 +373,7 @@ class TestMembership(TestClub):
|
|||||||
assert form.errors == {"role": ["Ce champ est obligatoire."]}
|
assert form.errors == {"role": ["Ce champ est obligatoire."]}
|
||||||
|
|
||||||
def test_add_member_already_there(self):
|
def test_add_member_already_there(self):
|
||||||
form = ClubMemberForm(
|
form = ClubAddMemberForm(
|
||||||
data={"user": self.simple_board_member, "role": 3},
|
data={"user": self.simple_board_member, "role": 3},
|
||||||
request_user=self.root,
|
request_user=self.root,
|
||||||
club=self.club,
|
club=self.club,
|
||||||
@@ -385,17 +387,14 @@ class TestMembership(TestClub):
|
|||||||
non_member = subscriber_user.make()
|
non_member = subscriber_user.make()
|
||||||
simple_member = baker.make(Membership, club=self.club, role=1).user
|
simple_member = baker.make(Membership, club=self.club, role=1).user
|
||||||
for user in non_member, simple_member:
|
for user in non_member, simple_member:
|
||||||
form = ClubMemberForm(
|
form = ClubAddMemberForm(
|
||||||
data={"user": subscriber_user.make(), "role": 1},
|
data={"user": subscriber_user.make(), "role": 1},
|
||||||
request_user=user,
|
request_user=user,
|
||||||
club=self.club,
|
club=self.club,
|
||||||
)
|
)
|
||||||
assert not form.is_valid()
|
assert not form.is_valid()
|
||||||
assert form.errors == {
|
assert form.errors == {
|
||||||
"__all__": [
|
"role": ["Sélectionnez un choix valide. 1 n\u2019en fait pas partie."]
|
||||||
"Vous ne pouvez pas ajouter d'autres utilisateurs "
|
|
||||||
"dans un club si vous ne faites pas partie de son bureau."
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_simple_members_dont_see_form_anymore(self):
|
def test_simple_members_dont_see_form_anymore(self):
|
||||||
@@ -533,6 +532,57 @@ class TestMembership(TestClub):
|
|||||||
assert new_board == initial_board
|
assert new_board == initial_board
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
class TestJoinClub:
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def clear_cache(self):
|
||||||
|
cache.clear()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("user_factory", "role", "errors"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
subscriber_user.make,
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"role": [
|
||||||
|
"Sélectionnez un choix valide. 2 n\u2019en fait pas partie."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
lambda: baker.make(User),
|
||||||
|
1,
|
||||||
|
{"__all__": ["Vous devez être cotisant pour faire partie d'un club"]},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_join_club_errors(
|
||||||
|
self, user_factory: Callable[[], User], role: int, errors: dict
|
||||||
|
):
|
||||||
|
club = baker.make(Club)
|
||||||
|
user = user_factory()
|
||||||
|
form = JoinClubForm(club=club, request_user=user, data={"role": role})
|
||||||
|
assert not form.is_valid()
|
||||||
|
assert form.errors == errors
|
||||||
|
|
||||||
|
def test_user_already_in_club(self):
|
||||||
|
club = baker.make(Club)
|
||||||
|
user = subscriber_user.make()
|
||||||
|
baker.make(Membership, user=user, club=club)
|
||||||
|
form = JoinClubForm(club=club, request_user=user, data={"role": 1})
|
||||||
|
assert not form.is_valid()
|
||||||
|
assert form.errors == {"__all__": ["Vous êtes déjà membre de ce club."]}
|
||||||
|
|
||||||
|
def test_ok(self):
|
||||||
|
club = baker.make(Club)
|
||||||
|
user = subscriber_user.make()
|
||||||
|
form = JoinClubForm(club=club, request_user=user, data={"role": 1})
|
||||||
|
assert form.is_valid()
|
||||||
|
form.save()
|
||||||
|
assert Membership.objects.ongoing().filter(user=user, club=club).exists()
|
||||||
|
|
||||||
|
|
||||||
class TestOldMembersView(TestCase):
|
class TestOldMembersView(TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
|
@@ -47,10 +47,11 @@ from django.views.generic import DetailView, ListView, View
|
|||||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||||
|
|
||||||
from club.forms import (
|
from club.forms import (
|
||||||
|
ClubAddMemberForm,
|
||||||
ClubAdminEditForm,
|
ClubAdminEditForm,
|
||||||
ClubEditForm,
|
ClubEditForm,
|
||||||
ClubMemberForm,
|
|
||||||
ClubOldMemberForm,
|
ClubOldMemberForm,
|
||||||
|
JoinClubForm,
|
||||||
MailingForm,
|
MailingForm,
|
||||||
SellingsForm,
|
SellingsForm,
|
||||||
)
|
)
|
||||||
@@ -266,17 +267,21 @@ class ClubAddMembersFragment(
|
|||||||
FragmentMixin, PermissionRequiredMixin, SuccessMessageMixin, CreateView
|
FragmentMixin, PermissionRequiredMixin, SuccessMessageMixin, CreateView
|
||||||
):
|
):
|
||||||
template_name = "club/fragments/add_member.jinja"
|
template_name = "club/fragments/add_member.jinja"
|
||||||
form_class = ClubMemberForm
|
|
||||||
model = Membership
|
model = Membership
|
||||||
object = None
|
object = None
|
||||||
reload_on_redirect = True
|
reload_on_redirect = True
|
||||||
permission_required = "club.view_club"
|
permission_required = "club.view_club"
|
||||||
success_message = _("%(user)s has been added to club.")
|
|
||||||
|
|
||||||
def dispatch(self, *args, **kwargs):
|
def dispatch(self, *args, **kwargs):
|
||||||
self.club = get_object_or_404(Club, pk=kwargs.get("club_id"))
|
self.club = get_object_or_404(Club, pk=kwargs.get("club_id"))
|
||||||
return super().dispatch(*args, **kwargs)
|
return super().dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_form_class(self):
|
||||||
|
user = self.request.user
|
||||||
|
if user.has_perm("club.add_membership") or self.club.get_membership_for(user):
|
||||||
|
return ClubAddMemberForm
|
||||||
|
return JoinClubForm
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
return super().get_form_kwargs() | {
|
return super().get_form_kwargs() | {
|
||||||
"request_user": self.request.user,
|
"request_user": self.request.user,
|
||||||
@@ -293,6 +298,11 @@ class ClubAddMembersFragment(
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
return super().get_context_data(**kwargs) | {"club": self.club}
|
return super().get_context_data(**kwargs) | {"club": self.club}
|
||||||
|
|
||||||
|
def get_success_message(self, cleaned_data):
|
||||||
|
if "user" not in cleaned_data or cleaned_data["user"] == self.request.user:
|
||||||
|
return _("You are now a member of this club.")
|
||||||
|
return _("%(user)s has been added to club.") % cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class ClubMembersView(
|
class ClubMembersView(
|
||||||
ClubTabsMixin, UseFragmentsMixin, PermissionRequiredMixin, DetailFormView
|
ClubTabsMixin, UseFragmentsMixin, PermissionRequiredMixin, DetailFormView
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-09-25 15:33+0200\n"
|
"POT-Creation-Date: 2025-09-26 17:36+0200\n"
|
||||||
"PO-Revision-Date: 2016-07-18\n"
|
"PO-Revision-Date: 2016-07-18\n"
|
||||||
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
||||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||||
@@ -174,14 +174,12 @@ msgid "You can not add the same user twice"
|
|||||||
msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
|
msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
|
||||||
|
|
||||||
#: club/forms.py
|
#: club/forms.py
|
||||||
msgid "You cannot add other users to a club if you are not in the club board."
|
msgid "You must be subscribed to join a club"
|
||||||
msgstr ""
|
msgstr "Vous devez être cotisant pour faire partie d'un club"
|
||||||
"Vous ne pouvez pas ajouter d'autres utilisateurs dans un club si vous ne "
|
|
||||||
"faites pas partie de son bureau."
|
|
||||||
|
|
||||||
#: club/forms.py sas/forms.py
|
#: club/forms.py
|
||||||
msgid "You do not have the permission to do that"
|
msgid "You are already a member of this club"
|
||||||
msgstr "Vous n'avez pas la permission de faire cela"
|
msgstr "Vous êtes déjà membre de ce club."
|
||||||
|
|
||||||
#: club/models.py
|
#: club/models.py
|
||||||
msgid "slug name"
|
msgid "slug name"
|
||||||
@@ -328,10 +326,6 @@ msgstr "Il n'y a pas de club dans ce site web."
|
|||||||
msgid "Club members"
|
msgid "Club members"
|
||||||
msgstr "Membres du club"
|
msgstr "Membres du club"
|
||||||
|
|
||||||
#: club/templates/club/club_members.jinja
|
|
||||||
msgid "Add a new member"
|
|
||||||
msgstr "Ajouter un nouveau membre"
|
|
||||||
|
|
||||||
#: club/templates/club/club_members.jinja
|
#: club/templates/club/club_members.jinja
|
||||||
#: club/templates/club/club_old_members.jinja
|
#: club/templates/club/club_old_members.jinja
|
||||||
#: core/templates/core/user_clubs.jinja
|
#: core/templates/core/user_clubs.jinja
|
||||||
@@ -570,12 +564,24 @@ msgstr ""
|
|||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Sauver"
|
msgstr "Sauver"
|
||||||
|
|
||||||
|
#: club/templates/club/fragments/add_member.jinja
|
||||||
|
msgid "Add a new member"
|
||||||
|
msgstr "Ajouter un nouveau membre"
|
||||||
|
|
||||||
|
#: club/templates/club/fragments/add_member.jinja
|
||||||
|
msgid "Join club"
|
||||||
|
msgstr "Rejoindre le club"
|
||||||
|
|
||||||
#: club/templates/club/fragments/add_member.jinja
|
#: club/templates/club/fragments/add_member.jinja
|
||||||
#: core/templates/core/file_detail.jinja core/views/forms.py
|
#: core/templates/core/file_detail.jinja core/views/forms.py
|
||||||
#: trombi/templates/trombi/detail.jinja
|
#: trombi/templates/trombi/detail.jinja
|
||||||
msgid "Add"
|
msgid "Add"
|
||||||
msgstr "Ajouter"
|
msgstr "Ajouter"
|
||||||
|
|
||||||
|
#: club/templates/club/fragments/add_member.jinja
|
||||||
|
msgid "Join"
|
||||||
|
msgstr "Rejoindre"
|
||||||
|
|
||||||
#: club/templates/club/mailing.jinja
|
#: club/templates/club/mailing.jinja
|
||||||
msgid "Mailing lists"
|
msgid "Mailing lists"
|
||||||
msgstr "Mailing listes"
|
msgstr "Mailing listes"
|
||||||
@@ -687,6 +693,10 @@ msgstr "Listes de diffusion"
|
|||||||
msgid "%(user)s has been added to club."
|
msgid "%(user)s has been added to club."
|
||||||
msgstr "%(user)s a été ajouté au club."
|
msgstr "%(user)s a été ajouté au club."
|
||||||
|
|
||||||
|
#: club/views.py
|
||||||
|
msgid "You are now a member of this club."
|
||||||
|
msgstr "Vous êtes maintenant membre de ce club."
|
||||||
|
|
||||||
#: com/forms.py
|
#: com/forms.py
|
||||||
msgid "Format: 16:9 | Resolution: 1920x1080"
|
msgid "Format: 16:9 | Resolution: 1920x1080"
|
||||||
msgstr "Format : 16:9 | Résolution : 1920x1080"
|
msgstr "Format : 16:9 | Résolution : 1920x1080"
|
||||||
@@ -4657,6 +4667,10 @@ msgstr "Pas de ban actif"
|
|||||||
msgid "Add a new album"
|
msgid "Add a new album"
|
||||||
msgstr "Ajouter un nouvel album"
|
msgstr "Ajouter un nouvel album"
|
||||||
|
|
||||||
|
#: sas/forms.py
|
||||||
|
msgid "You do not have the permission to do that"
|
||||||
|
msgstr "Vous n'avez pas la permission de faire cela"
|
||||||
|
|
||||||
#: sas/forms.py
|
#: sas/forms.py
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Envoyer les images"
|
msgstr "Envoyer les images"
|
||||||
@@ -5558,4 +5572,4 @@ msgstr "Vous ne pouvez plus écrire de commentaires, la date est passée."
|
|||||||
#: trombi/views.py
|
#: trombi/views.py
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Maximum characters: %(max_length)s"
|
msgid "Maximum characters: %(max_length)s"
|
||||||
msgstr "Nombre de caractères max: %(max_length)s"
|
msgstr "Nombre de caractères max: %(max_length)s"
|
||||||
|
Reference in New Issue
Block a user