News moderation buttons directly on the home page

This commit is contained in:
imperosol 2025-01-20 18:02:24 +01:00
parent 185fb70dda
commit 2ca3286f0f
7 changed files with 244 additions and 78 deletions

View File

@ -0,0 +1,39 @@
import { exportToHtml } from "#core:utils/globals";
import Alpine from "alpinejs";
import { newsDeleteNews, newsModerateNews } from "#openapi";
// This will be used in jinja templates,
// so we cannot use real enums as those are purely an abstraction of Typescript
const AlertState = {
// biome-ignore lint/style/useNamingConvention: this feels more like an enum
PENDING: 1,
// biome-ignore lint/style/useNamingConvention: this feels more like an enum
MODERATED: 2,
// biome-ignore lint/style/useNamingConvention: this feels more like an enum
DELETED: 3,
};
exportToHtml("AlertState", AlertState);
document.addEventListener("alpine:init", () => {
Alpine.data("moderationAlert", (newsId: number) => ({
state: AlertState.PENDING,
newsId: newsId as number,
loading: false,
async moderateNews() {
this.loading = true;
// biome-ignore lint/style/useNamingConvention: api is snake case
await newsModerateNews({ path: { news_id: this.newsId } });
this.state = AlertState.MODERATED;
this.loading = false;
},
async deleteNews() {
this.loading = true;
// biome-ignore lint/style/useNamingConvention: api is snake case
await newsDeleteNews({ path: { news_id: this.newsId } });
this.state = AlertState.DELETED;
this.loading = false;
},
}));
});

View File

@ -171,7 +171,9 @@
}
.news_event {
display: block;
display: flex;
flex-direction: column;
gap: .5em;
padding: 1em;
header {

View File

@ -0,0 +1,73 @@
{% macro news_moderation_alert(news, user, alpineState = None) %}
{# An alert to display on top of non moderated news,
with actions to either moderate or delete them.
The current state of the alert is accessible through
the given `alpineState` variable.
This state is a `AlertState`, as defined in `moderation-alert-index.ts`
Example :
```jinja
<div x-data="{state: AlertState.PENDING}">
{{ news_moderation_alert(news, user, "state") }}
</div>
```
Args:
news: The `News` object to which this alert is related
user: The request.user
alpineState: An alpine variable name
Warning:
If you use this macro, you must also include `moderation-alert-index.ts`
in your template.
#}
<div
x-data="moderationAlert({{ news.id }})"
{% if alpineState %}
x-modelable="{{ alpineState }}"
x-model="state"
{% endif %}
>
<template x-if="state === AlertState.PENDING">
<div class="alert alert-yellow">
<div class="alert-main">
<strong>{% trans %}Waiting moderation{% endtrans %}</strong>
<p>
{% trans trimmed %}
This news isn't moderated and is visible
only by its author and the communication admins.
{% endtrans %}
</p>
<p>
{% trans trimmed %}
It will stay hidden for other users until it has been moderated.
{% endtrans %}
</p>
</div>
{% if user.has_perm("com.moderate_news") %}
<span class="alert-aside" :aria-busy="loading">
<button class="btn btn-green" @click="moderateNews()" :disabled="loading">
<i class="fa fa-check"></i> {% trans %}Moderate{% endtrans %}
</button>
{% endif %}
{% if user.has_perm("com.delete_news") %}
<button class="btn btn-red" @click="deleteNews()" :disabled="loading">
<i class="fa fa-trash-can"></i> {% trans %}Delete{% endtrans %}
</button>
</span>
{% endif %}
</div>
</template>
<template x-if="state === AlertState.MODERATED">
<div class="alert alert-green">
{% trans %}News moderated{% endtrans %}
</div>
</template>
<template x-if="state === AlertState.DELETED">
<div class="alert alert-red">
{% trans %}News deleted{% endtrans %}
</div>
</template>
</div>
{% endmacro %}

View File

@ -1,5 +1,6 @@
{% extends "core/base.jinja" %}
{% from 'core/macros.jinja' import user_profile_link, facebook_share, tweet, link_news_logo, gen_news_metatags %}
{% from "com/macros.jinja" import news_moderation_alert %}
{% block title %}
{% trans %}News{% endtrans %} -
@ -16,9 +17,18 @@
<link rel="stylesheet" href="{{ static('com/css/news-detail.scss') }}">
{% endblock %}
{% block additional_js %}
<script type="module" src={{ static("bundled/com/components/moderation-alert-index.ts") }}></script>
{% endblock %}
{% block content %}
<p><a href="{{ url('com:news_list') }}">{% trans %}Back to news{% endtrans %}</a></p>
<section id="news_details">
<div x-data="{newsState: AlertState.PENDING}">
{% if not news.is_moderated %}
{{ news_moderation_alert(news, user, "newsState") }}
{% endif %}
<article id="news_details" x-show="newsState !== AlertState.DELETED">
<div class="club_logo">
<img src="{{ link_news_logo(news)}}" alt="{{ news.club }}" />
<a href="{{ news.club.get_absolute_url() }}">{{ news.club }}</a>
@ -48,7 +58,8 @@
{% endif %}
</div>
</div>
</section>
</article>
</div>
{% endblock %}

View File

@ -1,4 +1,5 @@
{% extends "core/base.jinja" %}
{% from "com/macros.jinja" import news_moderation_alert %}
{% block title %}
{% trans %}News{% endtrans %}
@ -14,6 +15,7 @@
{% block additional_js %}
<script type="module" src={{ static("bundled/com/components/ics-calendar-index.ts") }}></script>
<script type="module" src={{ static("bundled/com/components/moderation-alert-index.ts") }}></script>
{% endblock %}
{% block content %}
@ -46,7 +48,13 @@
</div>
<div class="news_events_group_items">
{% for date in dates_group %}
<article class="news_event">
<article class="news_event" x-data="{newsState: AlertState.PENDING}">
{% if not date.news.is_moderated %}
{# if a non moderated news is in the object list,
the logged user is either an admin or the news author #}
{{ news_moderation_alert(date.news, user, "newsState") }}
{% endif %}
<div x-show="newsState !== AlertState.DELETED">
<header class="row gap">
{% if date.news.club.logo %}
<img src="{{ date.news.club.logo.url }}" alt="{{ date.news.club }}"/>
@ -73,6 +81,7 @@
<div class="news_content markdown">
{{ date.news.summary|markdown }}
</div>
</div>
</article>
{% endfor %}
</div>

View File

@ -244,6 +244,20 @@ body {
}
}
&.btn-green {
$bg-color: rgba(0, 210, 83, 0.4);
background-color: $bg-color;
color: $black-color;
&:not(:disabled):hover {
background-color: darken($bg-color, 15%);
}
&:disabled {
background-color: lighten($bg-color, 15%);
}
}
&.btn-red {
background-color: #fc8181;
color: black;

View File

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-19 18:12+0100\n"
"POT-Creation-Date: 2025-01-20 17:35+0100\n"
"PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
"Language-Team: AE info <ae.info@utbm.fr>\n"
@ -310,7 +310,7 @@ msgstr "Compte en banque : "
#: accounting/templates/accounting/club_account_details.jinja
#: accounting/templates/accounting/label_list.jinja
#: club/templates/club/club_sellings.jinja club/templates/club/mailing.jinja
#: com/templates/com/mailing_admin.jinja
#: com/templates/com/macros.jinja com/templates/com/mailing_admin.jinja
#: com/templates/com/news_admin_list.jinja com/templates/com/poster_edit.jinja
#: com/templates/com/screen_edit.jinja com/templates/com/weekmail.jinja
#: core/templates/core/file_detail.jinja
@ -935,10 +935,6 @@ msgstr "rôle"
msgid "description"
msgstr "description"
#: club/models.py
msgid "past member"
msgstr "ancien membre"
#: club/models.py
msgid "Email address"
msgstr "Adresse email"
@ -1408,12 +1404,25 @@ msgstr "temps d'affichage"
msgid "Begin date should be before end date"
msgstr "La date de début doit être avant celle de fin"
#: com/templates/com/mailing_admin.jinja com/views.py
#: core/templates/core/user_tools.jinja
msgid "Mailing lists administration"
msgstr "Administration des mailing listes"
#: com/templates/com/macros.jinja
msgid "Waiting moderation"
msgstr "En attente de modération"
#: com/templates/com/mailing_admin.jinja
#: com/templates/com/macros.jinja
msgid ""
"This news isn't moderated 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 "
"admins communication."
#: com/templates/com/macros.jinja
msgid "It will stay hidden for other users until it has been moderated."
msgstr ""
"Elle sera cachée pour les autres utilisateurs tant qu'elle ne sera pas "
"modéré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
@ -1421,6 +1430,19 @@ msgstr "Administration des mailing listes"
msgid "Moderate"
msgstr "Modérer"
#: com/templates/com/macros.jinja
msgid "News moderated"
msgstr "Nouvelle modérée"
#: com/templates/com/macros.jinja
msgid "News deleted"
msgstr "Nouvelle supprimée"
#: com/templates/com/mailing_admin.jinja com/views.py
#: core/templates/core/user_tools.jinja
msgid "Mailing lists administration"
msgstr "Administration des mailing listes"
#: com/templates/com/mailing_admin.jinja
#, python-format
msgid "Moderated by %(user)s"
@ -1578,14 +1600,6 @@ msgstr "Discord AE"
msgid "Dev Team"
msgstr "Pôle Informatique"
#: com/templates/com/news_list.jinja
msgid "Facebook"
msgstr "Facebook"
#: com/templates/com/news_list.jinja
msgid "Instagram"
msgstr "Instagram"
#: com/templates/com/news_list.jinja
msgid "Birthdays"
msgstr "Anniversaires"
@ -1599,6 +1613,10 @@ msgstr "%(age)s ans"
msgid "You need to subscribe to access this content"
msgstr "Vous devez cotiser pour accéder à ce contenu"
#: com/templates/com/news_list.jinja
msgid "You cannot access this content"
msgstr "Vous n'avez pas accès à ce contenu"
#: com/templates/com/poster_edit.jinja com/templates/com/poster_list.jinja
msgid "Poster"
msgstr "Affiche"
@ -3299,8 +3317,8 @@ msgstr "Nom d'utilisateur, email, ou numéro de compte AE"
#: core/views/forms.py
msgid ""
"Profile: you need to be visible on the picture, in order to be recognized "
"(e.g. by the barmen)"
"Profile: you need to be visible on the picture, in order to be recognized (e."
"g. by the barmen)"
msgstr ""
"Photo de profil: vous devez être visible sur la photo afin d'être reconnu "
"(par exemple par les barmen)"
@ -3906,8 +3924,8 @@ msgstr ""
#: counter/templates/counter/mails/account_dump.jinja
msgid "If you think this was a mistake, please mail us at ae@utbm.fr."
msgstr ""
"Si vous pensez qu'il s'agit d'une erreur, veuillez envoyer un mail à "
"ae@utbm.fr."
"Si vous pensez qu'il s'agit d'une erreur, veuillez envoyer un mail à ae@utbm."
"fr."
#: counter/templates/counter/mails/account_dump.jinja
msgid ""