diff --git a/club/templates/club/club_sellings.jinja b/club/templates/club/club_sellings.jinja index 4928e356..3733d0c8 100644 --- a/club/templates/club/club_sellings.jinja +++ b/club/templates/club/club_sellings.jinja @@ -83,9 +83,10 @@ TODO : rewrite the pagination used in this template an Alpine one {{ paginate(paginated_result, paginator, "formPagination(this)") }} diff --git a/com/templates/com/poster_list.jinja b/com/templates/com/poster_list.jinja index 8afe5e42..d723c248 100644 --- a/com/templates/com/poster_list.jinja +++ b/com/templates/com/poster_list.jinja @@ -35,7 +35,7 @@
diff --git a/com/templates/com/weekmail.jinja b/com/templates/com/weekmail.jinja index f8b37cbf..1342d9b0 100644 --- a/com/templates/com/weekmail.jinja +++ b/com/templates/com/weekmail.jinja @@ -31,9 +31,7 @@ {% trans %}Edit{% endtrans %} | {% trans %}Delete{% endtrans %} | - {% trans %}Add to weekmail{% endtrans %} | - {% trans %}Up{% endtrans %} | - {% trans %}Down{% endtrans %} + {% trans %}Add to weekmail{% endtrans %} {% endfor %} diff --git a/com/views.py b/com/views.py index 1b58feac..a1897b12 100644 --- a/com/views.py +++ b/com/views.py @@ -28,6 +28,7 @@ from typing import Any from dateutil.relativedelta import relativedelta from django.conf import settings +from django.contrib import messages from django.contrib.auth.mixins import ( PermissionRequiredMixin, ) @@ -55,7 +56,7 @@ from core.auth.mixins import ( PermissionOrClubBoardRequiredMixin, ) from core.models import User -from core.views.mixins import QuickNotifMixin, TabedViewMixin +from core.views.mixins import TabedViewMixin from core.views.widgets.markdown import MarkdownInput # Sith object @@ -333,7 +334,7 @@ class NewsFeed(Feed): # Weekmail -class WeekmailPreviewView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, DetailView): +class WeekmailPreviewView(ComTabsMixin, CanEditPropMixin, DetailView): model = Weekmail template_name = "com/weekmail_preview.jinja" success_url = reverse_lazy("com:weekmail") @@ -345,12 +346,11 @@ class WeekmailPreviewView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, Detai def post(self, request, *args, **kwargs): self.object = self.get_object() + messages.success(self.request, _("Weekmail sent successfully")) if request.POST["send"] == "validate": try: self.object.send() - return HttpResponseRedirect( - reverse("com:weekmail") + "?qn_weekmail_send_success" - ) + return HttpResponseRedirect(reverse("com:weekmail")) except SMTPRecipientsRefused as e: self.bad_recipients = e.recipients elif request.POST["send"] == "clean": @@ -361,7 +361,6 @@ class WeekmailPreviewView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, Detai for u in users: u.preferences.receive_weekmail = False u.preferences.save() - self.quick_notif_list += ["qn_success"] return super().get(request, *args, **kwargs) def get_object(self, queryset=None): @@ -375,7 +374,7 @@ class WeekmailPreviewView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, Detai return kwargs -class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateView): +class WeekmailEditView(ComTabsMixin, CanEditPropMixin, UpdateView): model = Weekmail template_name = "com/weekmail.jinja" form_class = modelform_factory( @@ -415,7 +414,10 @@ class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateVi art.rank, prev_art.rank = prev_art.rank, art.rank art.save() prev_art.save() - self.quick_notif_list += ["qn_success"] + messages.success( + self.request, + _("%(title)s moved up in the Weekmail") % {"title": art.title}, + ) if "down_article" in request.GET: art = get_object_or_404( WeekmailArticle, id=request.GET["down_article"], weekmail=self.object @@ -427,7 +429,10 @@ class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateVi art.rank, next_art.rank = next_art.rank, art.rank art.save() next_art.save() - self.quick_notif_list += ["qn_success"] + messages.success( + self.request, + _("%(title)s moved down in the Weekmail") % {"title": art.title}, + ) if "add_article" in request.GET: art = get_object_or_404( WeekmailArticle, id=request.GET["add_article"], weekmail=None @@ -436,7 +441,10 @@ class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateVi art.rank = self.object.articles.aggregate(Max("rank"))["rank__max"] or 0 art.rank += 1 art.save() - self.quick_notif_list += ["qn_success"] + messages.success( + self.request, + _("%(title)s added to the Weekmail") % {"title": art.title}, + ) if "del_article" in request.GET: art = get_object_or_404( WeekmailArticle, id=request.GET["del_article"], weekmail=self.object @@ -444,7 +452,10 @@ class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateVi art.weekmail = None art.rank = -1 art.save() - self.quick_notif_list += ["qn_success"] + messages.success( + self.request, + _("%(title)s removed from the Weekmail") % {"title": art.title}, + ) return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): @@ -454,9 +465,7 @@ class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateVi return kwargs -class WeekmailArticleEditView( - ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateView -): +class WeekmailArticleEditView(ComTabsMixin, CanEditPropMixin, UpdateView): """Edit an article.""" model = WeekmailArticle @@ -468,11 +477,10 @@ class WeekmailArticleEditView( pk_url_kwarg = "article_id" template_name = "core/edit.jinja" success_url = reverse_lazy("com:weekmail") - quick_notif_url_arg = "qn_weekmail_article_edit" current_tab = "weekmail" -class WeekmailArticleCreateView(QuickNotifMixin, CreateView): +class WeekmailArticleCreateView(CreateView): """Post an article.""" model = WeekmailArticle @@ -483,7 +491,6 @@ class WeekmailArticleCreateView(QuickNotifMixin, CreateView): ) template_name = "core/create.jinja" success_url = reverse_lazy("core:user_tools") - quick_notif_url_arg = "qn_weekmail_new_article" def get_initial(self): if "club" not in self.request.GET: diff --git a/core/static/bundled/utils/notifications.ts b/core/static/bundled/utils/notifications.ts new file mode 100644 index 00000000..70e5fd91 --- /dev/null +++ b/core/static/bundled/utils/notifications.ts @@ -0,0 +1,25 @@ +export enum NotificationLevel { + Error = "error", + Warning = "warning", + Success = "success", +} + +export function createNotification(message: string, level: NotificationLevel) { + const element = document.getElementById("quick-notifications"); + if (element === null) { + return false; + } + return element.dispatchEvent( + new CustomEvent("quick-notification-add", { + detail: { text: message, tag: level }, + }), + ); +} + +export function deleteNotifications() { + const element = document.getElementById("quick-notifications"); + if (element === null) { + return false; + } + return element.dispatchEvent(new CustomEvent("quick-notification-delete")); +} diff --git a/core/static/core/header.scss b/core/static/core/header.scss index 348d3796..7eca52f9 100644 --- a/core/static/core/header.scss +++ b/core/static/core/header.scss @@ -321,7 +321,6 @@ $hovered-red-text-color: #ff4d4d; >#header_notif { box-sizing: border-box; - display: none; position: absolute; margin: 0; background-color: whitesmoke; diff --git a/core/static/core/js/script.js b/core/static/core/js/script.js deleted file mode 100644 index 9be232dd..00000000 --- a/core/static/core/js/script.js +++ /dev/null @@ -1,38 +0,0 @@ -$(() => { - $("#quick_notif li").click(function () { - $(this).hide(); - }); -}); - -// biome-ignore lint/correctness/noUnusedVariables: used in other scripts -function createQuickNotif(msg) { - const el = document.createElement("li"); - el.textContent = msg; - el.addEventListener("click", () => el.parentNode.removeChild(el)); - document.getElementById("quick_notif").appendChild(el); -} - -// biome-ignore lint/correctness/noUnusedVariables: used in other scripts -function deleteQuickNotifs() { - const el = document.getElementById("quick_notif"); - while (el.firstChild) { - el.removeChild(el.firstChild); - } -} - -// biome-ignore lint/correctness/noUnusedVariables: used in other scripts -function displayNotif() { - $("#header_notif").toggle().parent().toggleClass("white"); -} - -// You can't get the csrf token from the template in a widget -// We get it from a cookie as a workaround, see this link -// https://docs.djangoproject.com/en/2.0/ref/csrf/#ajax -// Sadly, getting the cookie is not possible with CSRF_COOKIE_HTTPONLY or CSRF_USE_SESSIONS is True -// So, the true workaround is to get the token from the dom -// https://docs.djangoproject.com/en/2.0/ref/csrf/#acquiring-the-token-if-csrf-use-sessions-is-true -// biome-ignore lint/style/useNamingConvention: can't find it used anywhere but I will not play with the devil -// biome-ignore lint/correctness/noUnusedVariables: used in other scripts -function getCSRFToken() { - return $("[name=csrfmiddlewaretoken]").val(); -} diff --git a/core/static/core/style.scss b/core/static/core/style.scss index 2baf42a6..771ca5e2 100644 --- a/core/static/core/style.scss +++ b/core/static/core/style.scss @@ -270,17 +270,6 @@ body { } /*--------------------------------CONTENT------------------------------*/ - #quick_notif { - width: 100%; - margin: 0 auto; - list-style-type: none; - background: $second-color; - - li { - padding: 10px; - } - } - #content { padding: 1em 1%; box-shadow: $shadow-color 0 5px 10px; diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 5fb6fd5f..2be6cd54 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -32,10 +32,6 @@ - - - - {% block additional_css %}{% endblock %} {% block additional_js %}{% endblock %} {% endblock %} @@ -74,17 +70,15 @@
- -
{%- block tabs -%} {% include "core/base/tabs.jinja" %} {%- endblock -%} + {% block notifications %} + {% include "core/base/notifications.jinja" %} + {% endblock %} + {%- block errors -%} {% if error %} {{ error }} diff --git a/core/templates/core/base/header.jinja b/core/templates/core/base/header.jinja index 4454aedb..87453d22 100644 --- a/core/templates/core/base/header.jinja +++ b/core/templates/core/base/header.jinja @@ -74,9 +74,9 @@ {% endif %} >
-
- - +
+ + {% set notification_count = user.notifications.filter(viewed=False).count() %} {% if notification_count > 0 %} @@ -89,7 +89,7 @@ {% endif %} -
+
    {% if user.notifications.filter(viewed=False).count() > 0 %} {% for n in user.notifications.filter(viewed=False).order_by('-date') %} diff --git a/core/templates/core/base/notifications.jinja b/core/templates/core/base/notifications.jinja new file mode 100644 index 00000000..b50ec89f --- /dev/null +++ b/core/templates/core/base/notifications.jinja @@ -0,0 +1,24 @@ +
    + +
    diff --git a/core/views/mixins.py b/core/views/mixins.py index 2a18955c..bdfb2908 100644 --- a/core/views/mixins.py +++ b/core/views/mixins.py @@ -2,7 +2,6 @@ import copy import inspect from typing import Any, ClassVar, LiteralString, Protocol, Unpack -from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.http import HttpRequest, HttpResponse from django.template.loader import render_to_string @@ -41,36 +40,6 @@ class TabedViewMixin(View): return kwargs -class QuickNotifMixin: - quick_notif_list = [] - - def dispatch(self, request, *arg, **kwargs): - # In some cases, the class can stay instanciated, so we need to reset the list - self.quick_notif_list = [] - return super().dispatch(request, *arg, **kwargs) - - def get_success_url(self): - ret = super().get_success_url() - if hasattr(self, "quick_notif_url_arg"): - if "?" in ret: - ret += "&" + self.quick_notif_url_arg - else: - ret += "?" + self.quick_notif_url_arg - return ret - - def get_context_data(self, **kwargs): - """Add quick notifications to context.""" - kwargs = super().get_context_data(**kwargs) - kwargs["quick_notifs"] = [] - for n in self.quick_notif_list: - kwargs["quick_notifs"].append(settings.SITH_QUICK_NOTIF[n]) - for key, val in settings.SITH_QUICK_NOTIF.items(): - for gk in self.request.GET: - if key == gk: - kwargs["quick_notifs"].append(val) - return kwargs - - class AllowFragment: """Add `is_fragment` to templates. It's only True if the request is emitted by htmx""" diff --git a/core/views/user.py b/core/views/user.py index 376950d2..ba7beaa9 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -65,7 +65,7 @@ from core.views.forms import ( UserGroupsForm, UserProfileForm, ) -from core.views.mixins import QuickNotifMixin, TabedViewMixin, UseFragmentsMixin +from core.views.mixins import TabedViewMixin, UseFragmentsMixin from counter.models import Counter, Refilling, Selling from eboutic.models import Invoice from subscription.models import Subscription @@ -564,7 +564,7 @@ class UserUpdateGroupView(UserTabsMixin, CanEditPropMixin, UpdateView): current_tab = "groups" -class UserToolsView(LoginRequiredMixin, QuickNotifMixin, UserTabsMixin, TemplateView): +class UserToolsView(LoginRequiredMixin, UserTabsMixin, TemplateView): """Displays the logged user's tools.""" template_name = "core/user_tools.jinja" diff --git a/docs/reference/core/mixins.md b/docs/reference/core/mixins.md index d08c1ee8..08ba0367 100644 --- a/docs/reference/core/mixins.md +++ b/docs/reference/core/mixins.md @@ -4,7 +4,6 @@ heading_level: 3 members: - TabedViewMixin - - QuickNotifMixin - AllowFragment - FragmentMixin - UseFragmentsMixin \ No newline at end of file diff --git a/eboutic/templates/eboutic/eboutic_billing_info.jinja b/eboutic/templates/eboutic/eboutic_billing_info.jinja index 8a5c8a83..429aac8b 100644 --- a/eboutic/templates/eboutic/eboutic_billing_info.jinja +++ b/eboutic/templates/eboutic/eboutic_billing_info.jinja @@ -31,12 +31,5 @@

- - {% if messages %} - {% for message in messages %} -
- {{ message }} -
- {% endfor %} - {% endif %} + {% include "core/base/notifications.jinja" %}
diff --git a/eboutic/templates/eboutic/eboutic_checkout.jinja b/eboutic/templates/eboutic/eboutic_checkout.jinja index bf467222..17210cc5 100644 --- a/eboutic/templates/eboutic/eboutic_checkout.jinja +++ b/eboutic/templates/eboutic/eboutic_checkout.jinja @@ -1,5 +1,9 @@ {% extends "core/base.jinja" %} +{% block notifications %} + {# Notifications are moved inside the billing info fragment #} +{% endblock %} + {% block title %} {% trans %}Basket state{% endtrans %} {% endblock %} diff --git a/eboutic/templates/eboutic/eboutic_main.jinja b/eboutic/templates/eboutic/eboutic_main.jinja index 1809d0b7..3ee0d745 100644 --- a/eboutic/templates/eboutic/eboutic_main.jinja +++ b/eboutic/templates/eboutic/eboutic_main.jinja @@ -22,14 +22,6 @@ {% block content %}

{% trans %}Eboutic{% endtrans %}

- {% if messages %} - {% for message in messages %} -
- {{ message }} -
- {% endfor %} - {% endif %} -

Panier

diff --git a/eboutic/templates/eboutic/eboutic_payment_result.jinja b/eboutic/templates/eboutic/eboutic_payment_result.jinja index 719ebc58..6c03754d 100644 --- a/eboutic/templates/eboutic/eboutic_payment_result.jinja +++ b/eboutic/templates/eboutic/eboutic_payment_result.jinja @@ -4,14 +4,6 @@

{% trans %}Eboutic{% endtrans %}

- {% if messages %} - {% for message in messages %} -
- {{ message }} -
- {% endfor %} - {% endif %} - {% if success %} {% trans %}Payment successful{% endtrans %} {% else %} diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 0c9cd5e5..f4bbbb45 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-09-22 14:29+0200\n" +"POT-Creation-Date: 2025-09-25 15:33+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Maréchal \n" @@ -1164,14 +1164,6 @@ msgstr "Contenu" msgid "Add to weekmail" msgstr "Ajouter au Weekmail" -#: com/templates/com/weekmail.jinja -msgid "Up" -msgstr "Monter" - -#: com/templates/com/weekmail.jinja -msgid "Down" -msgstr "Descendre" - #: com/templates/com/weekmail.jinja msgid "Articles included the next weekmail" msgstr "Article inclus dans le prochain Weekmail" @@ -1180,6 +1172,14 @@ msgstr "Article inclus dans le prochain Weekmail" msgid "Delete from weekmail" msgstr "Supprimer du Weekmail" +#: com/templates/com/weekmail.jinja +msgid "Up" +msgstr "Monter" + +#: com/templates/com/weekmail.jinja +msgid "Down" +msgstr "Descendre" + #: com/templates/com/weekmail_preview.jinja #: core/templates/core/user_account_detail.jinja #: pedagogy/templates/pedagogy/uv_detail.jinja @@ -1261,6 +1261,10 @@ msgstr "Liste d'écrans" msgid "All incoming events" msgstr "Tous les événements à venir" +#: com/views.py +msgid "Weekmail sent successfully" +msgstr "Weekmail envoyé avec succès" + #: com/views.py msgid "Delete and save to regenerate" msgstr "Supprimer et sauver pour régénérer" @@ -1269,6 +1273,26 @@ msgstr "Supprimer et sauver pour régénérer" msgid "Weekmail of the " msgstr "Weekmail du " +#: com/views.py +#, python-format +msgid "%(title)s moved up in the Weekmail" +msgstr "%(title)s monté dans le Weekmail" + +#: com/views.py +#, python-format +msgid "%(title)s moved down in the Weekmail" +msgstr "%(title)s descendu dans le Weekmail" + +#: com/views.py +#, python-format +msgid "%(title)s added to the Weekmail" +msgstr "%(title)s ajouté dans Weekmail" + +#: com/views.py +#, python-format +msgid "%(title)s removed from the Weekmail" +msgstr "%(title)s retiré du Weekmail" + #: com/views.py msgid "" "You must be a board member of the selected club to post in the Weekmail." @@ -4548,22 +4572,6 @@ msgstr "Signaler ce commentaire" msgid "Edit UE" msgstr "Éditer l'UE" -#: pedagogy/templates/pedagogy/uv_edit.jinja -msgid "Import from UTBM" -msgstr "Importer depuis l'UTBM" - -#: pedagogy/templates/pedagogy/uv_edit.jinja -msgid "Unknown UE code" -msgstr "Code d'UE inconnu" - -#: pedagogy/templates/pedagogy/uv_edit.jinja -msgid "Successful autocomplete" -msgstr "Autocomplétion réussite" - -#: pedagogy/templates/pedagogy/uv_edit.jinja -msgid "An error occurred: " -msgstr "Une erreur est survenue : " - #: rootplace/forms.py msgid "User that will be kept" msgstr "Utilisateur qui sera conservé" @@ -5116,26 +5124,6 @@ msgstr "Vous avez acheté %s" msgid "You have a notification" msgstr "Vous avez une notification" -#: sith/settings.py -msgid "Success!" -msgstr "Succès !" - -#: sith/settings.py -msgid "Fail!" -msgstr "Échec !" - -#: sith/settings.py -msgid "You successfully posted an article in the Weekmail" -msgstr "Article posté avec succès dans le Weekmail" - -#: sith/settings.py -msgid "You successfully edited an article in the Weekmail" -msgstr "Article édité avec succès dans le Weekmail" - -#: sith/settings.py -msgid "You successfully sent the Weekmail" -msgstr "Weekmail envoyé avec succès" - #: sith/settings.py msgid "AE tee-shirt" msgstr "Tee-shirt AE" @@ -5178,8 +5166,8 @@ msgstr "Vous ne pouvez pas cotiser plusieurs fois pour la même période" #: subscription/templates/subscription/forms/create_existing_user.jinja msgid "" -"If the subscription is done using the AE account, you must also click " -"it on the AE counter." +"If the subscription is done using the AE account, you must also click it on " +"the AE counter." msgstr "" "Si la cotisation est faite en utilisant le compte AE, vous devez également " "la cliquer sur le comptoir AE." @@ -5447,10 +5435,38 @@ msgstr "Mes photos" msgid "Admin tools" msgstr "Admin Trombi" +#: trombi/views.py +msgid "Trombi modified" +msgstr "Trombi modifié" + +#: trombi/views.py +msgid "User added to the trombi" +msgstr "Utilisateur ajouté au trombi" + +#: trombi/views.py +msgid "User couldn't be added to the trombi" +msgstr "L'utilisateur n'a pas pu être ajouté au trombi" + +#: trombi/views.py +msgid "User removed from the trombi" +msgstr "Utilisateur retiré du trombi" + #: trombi/views.py msgid "Explain why you rejected the comment" msgstr "Expliquez pourquoi vous refusez le commentaire" +#: trombi/views.py +msgid "Comment accepted" +msgstr "Commentaire accepté" + +#: trombi/views.py +msgid "Comment rejected" +msgstr "Commentaire rejeté" + +#: trombi/views.py +msgid "Comment removed" +msgstr "Commentaire retiré" + #: trombi/views.py msgid "Rejected comment" msgstr "Commentaire rejeté" @@ -5491,6 +5507,10 @@ msgstr "" "pouvez vous inscrire qu'à un seul Trombi, donc ne jouez pas avec cet option " "ou vous encourerez la colère des admins!" +#: trombi/views.py +msgid "User modified" +msgstr "Utilisateur modifié" + #: trombi/views.py msgid "Personal email (not UTBM)" msgstr "Email personnel (pas UTBM)" @@ -5503,6 +5523,14 @@ msgstr "Téléphone" msgid "Native town" msgstr "Ville d'origine" +#: trombi/views.py +msgid "User removed from trombi" +msgstr "Utilisateur retiré du trombi" + +#: trombi/views.py +msgid "Comment added" +msgstr "Commentaire ajouté" + #: trombi/views.py msgid "" "You can not yet write comment, you must wait for the subscription deadline " diff --git a/package-lock.json b/package-lock.json index 774d7396..74df5d10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "easymde": "^2.19.0", "glob": "^11.0.0", "htmx.org": "^2.0.3", - "jquery": "^3.7.1", "js-cookie": "^3.0.5", "lit-html": "^3.3.0", "native-file-system-adapter": "^3.0.1", @@ -47,7 +46,6 @@ "@types/alpinejs": "^3.13.10", "@types/cytoscape-cxtmenu": "^3.4.4", "@types/cytoscape-klay": "^3.1.4", - "@types/jquery": "^3.5.31", "@types/js-cookie": "^3.0.6", "typescript": "^5.8.3", "vite": "^6.3.6", @@ -2889,16 +2887,6 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, - "node_modules/@types/jquery": { - "version": "3.5.33", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.33.tgz", - "integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/sizzle": "*" - } - }, "node_modules/@types/js-cookie": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", @@ -2919,13 +2907,6 @@ "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==", "license": "MIT" }, - "node_modules/@types/sizzle": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.10.tgz", - "integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/tern": { "version": "0.23.9", "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", @@ -4384,12 +4365,6 @@ "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT" - }, "node_modules/js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", diff --git a/package.json b/package.json index 33363697..fedc2f8e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "@types/alpinejs": "^3.13.10", "@types/cytoscape-cxtmenu": "^3.4.4", "@types/cytoscape-klay": "^3.1.4", - "@types/jquery": "^3.5.31", "@types/js-cookie": "^3.0.6", "typescript": "^5.8.3", "vite": "^6.3.6", @@ -61,7 +60,6 @@ "easymde": "^2.19.0", "glob": "^11.0.0", "htmx.org": "^2.0.3", - "jquery": "^3.7.1", "js-cookie": "^3.0.5", "lit-html": "^3.3.0", "native-file-system-adapter": "^3.0.1", diff --git a/pedagogy/templates/pedagogy/uv_detail.jinja b/pedagogy/templates/pedagogy/uv_detail.jinja index 9b164583..4e4d315f 100644 --- a/pedagogy/templates/pedagogy/uv_detail.jinja +++ b/pedagogy/templates/pedagogy/uv_detail.jinja @@ -13,16 +13,15 @@ {% block content %}
-

{% trans %}Back{% endtrans %}

- +

{{ object.code }} - {{ object.title }}


@@ -217,9 +216,4 @@
- - {% endblock %} diff --git a/pedagogy/templates/pedagogy/uv_edit.jinja b/pedagogy/templates/pedagogy/uv_edit.jinja index b4869e14..c0709419 100644 --- a/pedagogy/templates/pedagogy/uv_edit.jinja +++ b/pedagogy/templates/pedagogy/uv_edit.jinja @@ -21,11 +21,6 @@ {{ field.errors }} {{ field }} - - - {% if field.name == 'code' %} - - {% endif %}

{% endif %} @@ -36,48 +31,3 @@

{% endblock %} - -{% block script %} - {{ super() }} - - -{% endblock %} diff --git a/sith/settings.py b/sith/settings.py index 7595ddd0..68e75173 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -685,14 +685,6 @@ SITH_PERMANENT_NOTIFICATIONS = { "SAS_MODERATION": "sas.models.sas_notification_callback", } -SITH_QUICK_NOTIF = { - "qn_success": _("Success!"), - "qn_fail": _("Fail!"), - "qn_weekmail_new_article": _("You successfully posted an article in the Weekmail"), - "qn_weekmail_article_edit": _("You successfully edited an article in the Weekmail"), - "qn_weekmail_send_success": _("You successfully sent the Weekmail"), -} - # Mailing related settings SITH_MAILING_DOMAIN = "utbm.fr" diff --git a/trombi/views.py b/trombi/views.py index f44458ee..a1978ec3 100644 --- a/trombi/views.py +++ b/trombi/views.py @@ -26,7 +26,9 @@ from datetime import date from django import forms from django.conf import settings +from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.messages.views import SuccessMessageMixin from django.core.exceptions import PermissionDenied from django.db import IntegrityError from django.forms.models import modelform_factory @@ -46,7 +48,7 @@ from core.auth.mixins import ( ) from core.models import User from core.views.forms import SelectDate -from core.views.mixins import QuickNotifMixin, TabedViewMixin +from core.views.mixins import TabedViewMixin from core.views.widgets.ajax_select import AutoCompleteSelectUser from trombi.models import Trombi, TrombiClubMembership, TrombiComment, TrombiUser @@ -134,15 +136,15 @@ class TrombiCreateView(CanCreateMixin, CreateView): return self.form_invalid(form) -class TrombiEditView(CanEditPropMixin, TrombiTabsMixin, UpdateView): +class TrombiEditView( + CanEditPropMixin, TrombiTabsMixin, SuccessMessageMixin, UpdateView +): model = Trombi form_class = TrombiForm template_name = "core/edit.jinja" pk_url_kwarg = "trombi_id" current_tab = "admin_tools" - - def get_success_url(self): - return super().get_success_url() + "?qn_success" + success_message = _("Trombi modified") class AddUserForm(forms.Form): @@ -155,7 +157,7 @@ class AddUserForm(forms.Form): ) -class TrombiDetailView(CanEditMixin, QuickNotifMixin, TrombiTabsMixin, DetailView): +class TrombiDetailView(CanEditMixin, TrombiTabsMixin, DetailView): model = Trombi template_name = "trombi/detail.jinja" pk_url_kwarg = "trombi_id" @@ -167,9 +169,9 @@ class TrombiDetailView(CanEditMixin, QuickNotifMixin, TrombiTabsMixin, DetailVie if form.is_valid(): try: TrombiUser(user=form.cleaned_data["user"], trombi=self.object).save() - self.quick_notif_list.append("qn_success") + messages.success(self.request, _("User added to the trombi")) except IntegrityError: # We don't care about duplicate keys - self.quick_notif_list.append("qn_fail") + messages.error(self.request, _("User couldn't be added to the trombi")) return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): @@ -185,22 +187,20 @@ class TrombiExportView(CanEditMixin, TrombiTabsMixin, DetailView): current_tab = "admin_tools" -class TrombiDeleteUserView(CanEditPropMixin, TrombiTabsMixin, DeleteView): +class TrombiDeleteUserView( + CanEditPropMixin, TrombiTabsMixin, SuccessMessageMixin, DeleteView +): model = TrombiUser pk_url_kwarg = "user_id" template_name = "core/delete_confirm.jinja" current_tab = "admin_tools" + success_message = _("User removed from the trombi") def get_success_url(self): - return ( - reverse("trombi:detail", kwargs={"trombi_id": self.object.trombi.id}) - + "?qn_success" - ) + return reverse("trombi:detail", kwargs={"trombi_id": self.object.trombi.id}) -class TrombiModerateCommentsView( - CanEditPropMixin, QuickNotifMixin, TrombiTabsMixin, DetailView -): +class TrombiModerateCommentsView(CanEditPropMixin, TrombiTabsMixin, DetailView): model = Trombi template_name = "trombi/comment_moderation.jinja" pk_url_kwarg = "trombi_id" @@ -235,16 +235,18 @@ class TrombiModerateCommentView(DetailView): if request.POST["action"] == "accept": self.object.is_moderated = True self.object.save() + messages.success(self.request, _("Comment accepted")) return redirect( reverse( "trombi:moderate_comments", kwargs={"trombi_id": self.object.author.trombi.id}, ) - + "?qn_success" ) elif request.POST["action"] == "reject": + messages.success(self.request, _("Comment rejected")) return super().get(request, *args, **kwargs) elif request.POST["action"] == "delete" and "reason" in request.POST: + messages.success(self.request, _("Comment removed")) self.object.author.user.email_user( subject="[%s] %s" % (settings.SITH_NAME, _("Rejected comment")), message=_( @@ -265,7 +267,6 @@ class TrombiModerateCommentView(DetailView): "trombi:moderate_comments", kwargs={"trombi_id": self.object.author.trombi.id}, ) - + "?qn_success" ) raise Http404 @@ -299,9 +300,7 @@ class UserTrombiForm(forms.Form): ) -class UserTrombiToolsView( - LoginRequiredMixin, QuickNotifMixin, TrombiTabsMixin, TemplateView -): +class UserTrombiToolsView(LoginRequiredMixin, TrombiTabsMixin, TemplateView): """Display a user's trombi tools.""" template_name = "trombi/user_tools.jinja" @@ -318,7 +317,6 @@ class UserTrombiToolsView( user=request.user, trombi=self.form.cleaned_data["trombi"] ) trombi_user.save() - self.quick_notif_list += ["qn_success"] return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): @@ -335,21 +333,24 @@ class UserTrombiToolsView( return kwargs -class UserTrombiEditPicturesView(TrombiTabsMixin, UserIsInATrombiMixin, UpdateView): +class UserTrombiEditPicturesView( + TrombiTabsMixin, UserIsInATrombiMixin, SuccessMessageMixin, UpdateView +): model = TrombiUser fields = ["profile_pict", "scrub_pict"] template_name = "core/edit.jinja" current_tab = "pictures" + success_message = _("User modified") def get_object(self): return self.request.user.trombi_user def get_success_url(self): - return reverse("trombi:user_tools") + "?qn_success" + return reverse("trombi:user_tools") class UserTrombiEditProfileView( - QuickNotifMixin, TrombiTabsMixin, UserIsInATrombiMixin, UpdateView + TrombiTabsMixin, UserIsInATrombiMixin, SuccessMessageMixin, UpdateView ): model = User form_class = modelform_factory( @@ -370,16 +371,20 @@ class UserTrombiEditProfileView( ) template_name = "trombi/edit_profile.jinja" current_tab = "profile" + success_message = _("User modified") def get_object(self): return self.request.user def get_success_url(self): - return reverse("trombi:user_tools") + "?qn_success" + return reverse("trombi:user_tools") -class UserTrombiResetClubMembershipsView(UserIsInATrombiMixin, RedirectView): +class UserTrombiResetClubMembershipsView( + UserIsInATrombiMixin, SuccessMessageMixin, RedirectView +): permanent = False + success_message = _("User modified") def get(self, request, *args, **kwargs): user = self.request.user.trombi_user @@ -387,18 +392,18 @@ class UserTrombiResetClubMembershipsView(UserIsInATrombiMixin, RedirectView): return redirect(self.get_success_url()) def get_success_url(self): - return reverse("trombi:profile") + "?qn_success" + return reverse("trombi:profile") -class UserTrombiDeleteMembershipView(TrombiTabsMixin, CanEditMixin, DeleteView): +class UserTrombiDeleteMembershipView( + TrombiTabsMixin, CanEditMixin, SuccessMessageMixin, DeleteView +): model = TrombiClubMembership pk_url_kwarg = "membership_id" template_name = "core/delete_confirm.jinja" success_url = reverse_lazy("trombi:profile") current_tab = "profile" - - def get_success_url(self): - return super().get_success_url() + "?qn_success" + success_message = _("User removed from trombi") # Used by admins when someone does not have every club in his list @@ -428,15 +433,18 @@ class UserTrombiAddMembershipView(TrombiTabsMixin, CreateView): ) -class UserTrombiEditMembershipView(CanEditMixin, TrombiTabsMixin, UpdateView): +class UserTrombiEditMembershipView( + CanEditMixin, TrombiTabsMixin, SuccessMessageMixin, UpdateView +): model = TrombiClubMembership pk_url_kwarg = "membership_id" fields = ["role", "start", "end"] template_name = "core/edit.jinja" current_tab = "profile" + success_message = _("User modified") def get_success_url(self): - return super().get_success_url() + "?qn_success" + return super().get_success_url() class UserTrombiProfileView(TrombiTabsMixin, DetailView): @@ -461,12 +469,13 @@ class UserTrombiProfileView(TrombiTabsMixin, DetailView): return super().get(request, *args, **kwargs) -class TrombiCommentFormView(LoginRequiredMixin, View): +class TrombiCommentFormView(LoginRequiredMixin, SuccessMessageMixin, View): """Create/edit a trombi comment.""" model = TrombiComment fields = ["content"] template_name = "trombi/comment.jinja" + success_message = _("Comment added") def get_form_class(self): self.trombi = self.request.user.trombi_user.trombi @@ -496,7 +505,7 @@ class TrombiCommentFormView(LoginRequiredMixin, View): ) def get_success_url(self): - return reverse("trombi:user_tools") + "?qn_success" + return reverse("trombi:user_tools") def get_context_data(self, **kwargs): kwargs = super().get_context_data(**kwargs) diff --git a/tsconfig.json b/tsconfig.json index 59a3642f..25b3cd17 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "allowSyntheticDefaultImports": true, "esModuleInterop": true, "resolveJsonModule": true, - "types": ["jquery", "alpinejs"], + "types": ["alpinejs"], "paths": { "#openapi": ["./staticfiles/generated/openapi/client/index.ts"], "#openapi:*": ["./staticfiles/generated/openapi/client/*"], diff --git a/vite.config.mts b/vite.config.mts index 604d9d78..d191d017 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -4,7 +4,6 @@ import inject from "@rollup/plugin-inject"; import { glob } from "glob"; import { type AliasOptions, type UserConfig, defineConfig } from "vite"; import type { Rollup } from "vite"; -import { viteStaticCopy } from "vite-plugin-static-copy"; import tsconfig from "./tsconfig.json"; const outDir = resolve(__dirname, "./staticfiles/generated/bundled"); @@ -87,17 +86,6 @@ export default defineConfig((config: UserConfig) => { Alpine: "alpinejs", htmx: "htmx.org", }), - viteStaticCopy({ - targets: [ - { - src: resolve(nodeModules, "jquery/dist/jquery.min.js"), - dest: vendored, - }, - ], - }), ], - optimizeDeps: { - include: ["jquery"], - }, } satisfies UserConfig; });