diff --git a/com/tests/test_api.py b/com/tests/test_api.py
index 257ee056..ba48f49c 100644
--- a/com/tests/test_api.py
+++ b/com/tests/test_api.py
@@ -129,14 +129,14 @@ class TestInternalCalendar:
@pytest.mark.django_db
class TestModerateNews:
- @pytest.mark.parametrize("news_is_moderated", [True, False])
- def test_moderation_ok(self, client: Client, news_is_moderated: bool): # noqa FBT
+ @pytest.mark.parametrize("news_is_published", [True, False])
+ def test_moderation_ok(self, client: Client, news_is_published: bool): # noqa FBT
user = baker.make(
User, user_permissions=[Permission.objects.get(codename="moderate_news")]
)
# The API call should work even if the news is initially moderated.
# In the latter case, the result should be a noop, rather than an error.
- news = baker.make(News, is_moderated=news_is_moderated)
+ news = baker.make(News, is_published=news_is_published)
initial_moderator = news.moderator
client.force_login(user)
response = client.patch(
@@ -147,22 +147,22 @@ class TestModerateNews:
# If it was already moderated, it should be a no-op, but not an error
assert response.status_code == 200
news.refresh_from_db()
- assert news.is_moderated
- if not news_is_moderated:
+ assert news.is_published
+ if not news_is_published:
assert news.moderator == user
else:
assert news.moderator == initial_moderator
def test_moderation_forbidden(self, client: Client):
user = baker.make(User)
- news = baker.make(News, is_moderated=False)
+ news = baker.make(News, is_published=False)
client.force_login(user)
response = client.patch(
reverse("api:moderate_news", kwargs={"news_id": news.id})
)
assert response.status_code == 403
news.refresh_from_db()
- assert not news.is_moderated
+ assert not news.is_published
@pytest.mark.django_db
@@ -203,7 +203,7 @@ class TestFetchNewsDates(TestCase):
value=now() + timedelta(hours=2), increment_by=timedelta(days=1)
),
news=iter(
- baker.make(News, is_moderated=True, _quantity=5, _bulk_create=True)
+ baker.make(News, is_published=True, _quantity=5, _bulk_create=True)
),
)
cls.dates.append(
@@ -211,7 +211,7 @@ class TestFetchNewsDates(TestCase):
NewsDate,
start_date=now() + timedelta(days=2, hours=1),
end_date=now() + timedelta(days=2, hours=5),
- news=baker.make(News, is_moderated=True),
+ news=baker.make(News, is_published=True),
)
)
cls.dates.sort(key=lambda d: d.start_date)
diff --git a/com/tests/test_models.py b/com/tests/test_models.py
index 41be34ee..f8536722 100644
--- a/com/tests/test_models.py
+++ b/com/tests/test_models.py
@@ -18,7 +18,7 @@ class TestNewsViewableBy(TestCase):
cls.news = baker.make(
News,
author=itertools.cycle(cls.users),
- is_moderated=iter([True, True, True, False, False, False]),
+ is_published=iter([True, True, True, False, False, False]),
_quantity=6,
_bulk_create=True,
)
diff --git a/com/tests/test_views.py b/com/tests/test_views.py
index f80839ab..ce96766e 100644
--- a/com/tests/test_views.py
+++ b/com/tests/test_views.py
@@ -168,7 +168,7 @@ class TestNews(TestCase):
assert not self.new.can_be_viewed_by(self.sli)
assert not self.new.can_be_viewed_by(self.anonymous)
- self.new.is_moderated = True
+ self.new.is_published = True
self.new.save()
assert self.new.can_be_viewed_by(self.com_admin)
assert self.new.can_be_viewed_by(self.sli)
@@ -258,7 +258,7 @@ class TestNewsCreation(TestCase):
created = News.objects.order_by("id").last()
assertRedirects(response, created.get_absolute_url())
assert created.title == "Test news"
- assert not created.is_moderated
+ assert not created.is_published
dates = list(created.dates.values("start_date", "end_date"))
assert dates == [{"start_date": self.start, "end_date": self.end}]
@@ -281,7 +281,7 @@ class TestNewsCreation(TestCase):
]
def test_edit_news(self):
- news = baker.make(News, author=self.user, is_moderated=True)
+ news = baker.make(News, author=self.user, is_published=True)
baker.make(
NewsDate,
news=news,
@@ -296,7 +296,7 @@ class TestNewsCreation(TestCase):
created = News.objects.order_by("id").last()
assertRedirects(response, created.get_absolute_url())
assert created.title == "Test news"
- assert not created.is_moderated
+ assert not created.is_published
dates = list(created.dates.values("start_date", "end_date"))
assert dates == [{"start_date": self.start, "end_date": self.end}]
diff --git a/com/views.py b/com/views.py
index ac29eb4a..e1114e57 100644
--- a/com/views.py
+++ b/com/views.py
@@ -217,9 +217,9 @@ class NewsModerateView(PermissionRequiredMixin, DetailView):
def get(self, request, *args, **kwargs):
self.object = self.get_object()
if "remove" in request.GET:
- self.object.is_moderated = False
+ self.object.is_published = False
else:
- self.object.is_moderated = True
+ self.object.is_published = True
self.object.moderator = request.user
self.object.save()
if "next" in self.request.GET:
@@ -253,7 +253,7 @@ class NewsListView(TemplateView):
key=lambda u: u.date_of_birth.year,
)
- def get_last_day(self) -> date:
+ def get_last_day(self) -> date | None:
"""Get the last day when news will be displayed
The returned day is the third one where something happen.
@@ -261,31 +261,37 @@ class NewsListView(TemplateView):
D on 20/03, E on 21/03 and F on 22/03 ;
then the result is 20/03.
"""
- return list(
+ dates = list(
NewsDate.objects.filter(end_date__gt=now())
.order_by("start_date")
.values_list("start_date__date", flat=True)
.distinct()[:4]
- )[-1]
+ )
+ return dates[-1] if len(dates) > 0 else None
- def get_news_dates(self, until: date):
+ def get_news_dates(self, until: date) -> dict[date, list[date]]:
"""Return the event dates to display.
The selected events are the ones that happens between
right now and the given day (included).
"""
- return itertools.groupby(
- NewsDate.objects.viewable_by(self.request.user)
- .filter(end_date__gt=now(), start_date__date__lte=until)
- .order_by("start_date")
- .select_related("news", "news__club"),
- key=lambda d: d.start_date.date(),
- )
+ return {
+ date: list(dates)
+ for date, dates in itertools.groupby(
+ NewsDate.objects.viewable_by(self.request.user)
+ .filter(end_date__gt=now(), start_date__date__lte=until)
+ .order_by("start_date")
+ .select_related("news", "news__club"),
+ key=lambda d: d.start_date.date(),
+ )
+ }
def get_context_data(self, **kwargs):
last_day = self.get_last_day()
return super().get_context_data(**kwargs) | {
- "news_dates": self.get_news_dates(until=last_day),
+ "news_dates": self.get_news_dates(until=last_day)
+ if last_day is not None
+ else {},
"birthdays": self.get_birthdays(),
"last_day": last_day,
}
@@ -309,7 +315,7 @@ class NewsFeed(Feed):
def items(self):
return (
NewsDate.objects.filter(
- news__is_moderated=True,
+ news__is_published=True,
end_date__gte=timezone.now() - (relativedelta(months=6)),
)
.select_related("news", "news__author")
diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py
index 82dd2516..21fde2e5 100644
--- a/core/management/commands/populate.py
+++ b/core/management/commands/populate.py
@@ -690,7 +690,7 @@ Welcome to the wiki page!
content="Glou glou glou glou glou glou glou",
club=bar_club,
author=subscriber,
- is_moderated=True,
+ is_published=True,
moderator=skia,
)
news_dates.append(
@@ -704,12 +704,11 @@ Welcome to the wiki page!
title="Repas barman",
summary="Enjoy la fin du semestre!",
content=(
- "Viens donc t'enjailler avec les autres barmans aux "
- "frais du BdF! \\o/"
+ "Viens donc t'enjailler avec les autres barmans aux frais du BdF! \\o/"
),
club=bar_club,
author=subscriber,
- is_moderated=True,
+ is_published=True,
moderator=skia,
)
news_dates.append(
@@ -725,7 +724,7 @@ Welcome to the wiki page!
content="Fô viendre mangey d'la bonne fondue!",
club=bar_club,
author=subscriber,
- is_moderated=True,
+ is_published=True,
moderator=skia,
)
news_dates.append(
@@ -741,7 +740,7 @@ Welcome to the wiki page!
content="Viens faire la fête avec tout plein de gens!",
club=bar_club,
author=subscriber,
- is_moderated=True,
+ is_published=True,
moderator=skia,
)
news_dates.append(
@@ -759,7 +758,7 @@ Welcome to the wiki page!
"t'amuser le Vendredi soir!",
club=troll,
author=subscriber,
- is_moderated=True,
+ is_published=True,
moderator=skia,
)
news_dates.extend(
diff --git a/core/migrations/0044_alter_userban_options.py b/core/migrations/0044_alter_userban_options.py
new file mode 100644
index 00000000..8dd1739e
--- /dev/null
+++ b/core/migrations/0044_alter_userban_options.py
@@ -0,0 +1,16 @@
+# Generated by Django 4.2.17 on 2025-02-25 14:45
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("core", "0043_bangroup_alter_group_description_alter_user_groups_and_more"),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name="userban",
+ options={"verbose_name": "user ban", "verbose_name_plural": "user bans"},
+ ),
+ ]
diff --git a/core/static/core/style.scss b/core/static/core/style.scss
index 22c8a583..6b037995 100644
--- a/core/static/core/style.scss
+++ b/core/static/core/style.scss
@@ -272,6 +272,20 @@ body {
}
}
+ &.btn-orange {
+ background-color: #fcbf81;
+ color: black;
+
+ &:not(:disabled):hover {
+ background-color: darken(#fcbf81, 15%);
+ }
+
+ &:disabled {
+ background-color: lighten(#fcbf81, 15%);
+ color: grey;
+ }
+ }
+
&:not(.btn-no-text) {
i {
margin-right: 4px;
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index d27dccd6..19b164df 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2025-02-25 11:04+0100\n"
+"POT-Creation-Date: 2025-02-25 16:38+0100\n"
"PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Maréchal
\n"
@@ -812,7 +812,7 @@ msgstr "Nouvelle mailing liste"
msgid "Subscribe"
msgstr "S'abonner"
-#: club/forms.py com/templates/com/news_admin_list.jinja
+#: club/forms.py
msgid "Remove"
msgstr "Retirer"
@@ -1296,8 +1296,8 @@ msgstr ""
"Combien de fois l'événement doit-il se répéter (en incluant la première fois)"
#: com/forms.py
-msgid "Automoderation"
-msgstr "Automodération"
+msgid "Auto publication"
+msgstr "Publication automatique"
#: com/models.py
msgid "alert message"
@@ -1344,6 +1344,10 @@ msgstr "Le club qui organise l'évènement."
msgid "author"
msgstr "auteur"
+#: com/models.py
+msgid "is published"
+msgstr "est publié"
+
#: com/models.py
msgid "news"
msgstr "nouvelle"
@@ -1409,34 +1413,31 @@ msgid "Begin date should be before end date"
msgstr "La date de début doit être avant celle de fin"
#: com/templates/com/macros.jinja
-msgid "Waiting moderation"
-msgstr "En attente de modération"
+msgid "Waiting publication"
+msgstr "En attente de publication"
#: com/templates/com/macros.jinja
msgid ""
-"This news isn't moderated and is visible only by its author and the "
+"This news isn't published and is visible only by its author and the "
"communication admins."
msgstr ""
-"Cette nouvelle n'est pas modérée et n'est visible que par son auteur et les "
+"Cette nouvelle n'est pas publiée et n'est visible que par son auteur et les "
"admins communication."
#: com/templates/com/macros.jinja
-msgid "It will stay hidden for other users until it has been moderated."
+msgid "It will stay hidden for other users until it has been published."
msgstr ""
"Elle sera cachée pour les autres utilisateurs tant qu'elle ne sera pas "
-"modérée."
+"publiée."
-#: com/templates/com/macros.jinja com/templates/com/mailing_admin.jinja
-#: com/templates/com/news_admin_list.jinja com/templates/com/news_detail.jinja
-#: core/templates/core/file_detail.jinja
-#: core/templates/core/file_moderation.jinja sas/templates/sas/moderation.jinja
-#: sas/templates/sas/picture.jinja
-msgid "Moderate"
-msgstr "Modérer"
+#: com/templates/com/macros.jinja com/templates/com/news_admin_list.jinja
+#: com/templates/com/news_detail.jinja
+msgid "Publish"
+msgstr "Publier"
#: com/templates/com/macros.jinja
-msgid "News moderated"
-msgstr "Nouvelle modérée"
+msgid "News published"
+msgstr "Nouvelle publiée"
#: com/templates/com/macros.jinja
msgid "News deleted"
@@ -1447,6 +1448,12 @@ msgstr "Nouvelle supprimée"
msgid "Mailing lists administration"
msgstr "Administration des mailing listes"
+#: com/templates/com/mailing_admin.jinja core/templates/core/file_detail.jinja
+#: core/templates/core/file_moderation.jinja sas/templates/sas/moderation.jinja
+#: sas/templates/sas/picture.jinja
+msgid "Moderate"
+msgstr "Modérer"
+
#: com/templates/com/mailing_admin.jinja
#, python-format
msgid "Moderated by %(user)s"
@@ -1514,6 +1521,10 @@ msgstr "Modérateur"
msgid "Dates"
msgstr "Dates"
+#: com/templates/com/news_admin_list.jinja
+msgid "Unpublish"
+msgstr "Dépublier"
+
#: com/templates/com/news_admin_list.jinja
msgid "Weeklies to moderate"
msgstr "Nouvelles hebdomadaires à modérer"
@@ -6031,13 +6042,3 @@ msgstr "Vous ne pouvez plus écrire de commentaires, la date est passée."
#, python-format
msgid "Maximum characters: %(max_length)s"
msgstr "Nombre de caractères max: %(max_length)s"
-
-#, python-format
-#~ msgid ""
-#~ "This event will take place every week for %%s weeks. If you moderate or "
-#~ "delete this event, it will also be moderated (or deleted) for the "
-#~ "following weeks."
-#~ msgstr ""
-#~ "Cet événement se déroulera chaque semaine pendant %%s semaines. Si vous "
-#~ "modérez ou supprimez cet événement, il sera également modéré (ou "
-#~ "supprimé) pour les semaines suivantes."
diff --git a/locale/fr/LC_MESSAGES/djangojs.po b/locale/fr/LC_MESSAGES/djangojs.po
index 6d6a483d..c222636a 100644
--- a/locale/fr/LC_MESSAGES/djangojs.po
+++ b/locale/fr/LC_MESSAGES/djangojs.po
@@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2025-02-25 11:05+0100\n"
+"POT-Creation-Date: 2025-02-25 16:10+0100\n"
"PO-Revision-Date: 2024-09-17 11:54+0200\n"
"Last-Translator: Sli \n"
"Language-Team: AE info \n"
@@ -21,15 +21,25 @@ msgstr ""
msgid "More info"
msgstr "Plus d'informations"
+#: com/static/bundled/com/components/ics-calendar-index.ts
+msgid "Publish"
+msgstr "Publier"
+
+#: com/static/bundled/com/components/ics-calendar-index.ts
+msgid "Unpublish"
+msgstr "Dépublier"
+
+#: com/static/bundled/com/components/ics-calendar-index.ts
+msgid "Delete"
+msgstr "Supprimer"
+
#: com/static/bundled/com/components/moderation-alert-index.ts
-#, javascript-format
msgid ""
-"This event will take place every week for %s weeks. If you moderate or "
-"delete this event, it will also be moderated (or deleted) for the following "
-"weeks."
+"This event will take place every week for %s weeks. If you publish or delete "
+"this event, it will also be published (or deleted) for the following weeks."
msgstr ""
"Cet événement se déroulera chaque semaine pendant %s semaines. Si vous "
-"modérez ou supprimez cet événement, il sera également modéré (ou supprimé) "
+"publiez ou supprimez cet événement, il sera également publié (ou supprimé) "
"pour les semaines suivantes."
#: core/static/bundled/core/components/ajax-select-base.ts
diff --git a/tsconfig.json b/tsconfig.json
index aaee9330..a93da92a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,6 +12,7 @@
"esModuleInterop": true,
"resolveJsonModule": true,
"types": ["jquery", "alpinejs"],
+ "lib": ["es7"],
"paths": {
"#openapi": ["./staticfiles/generated/openapi/index.ts"],
"#core:*": ["./core/static/bundled/*"],