From 63736a6c6088875b326091281f37b5ab0b17b41e Mon Sep 17 00:00:00 2001 From: Sli Date: Thu, 14 Nov 2024 12:01:57 +0100 Subject: [PATCH] Convert nfc input to a web component --- .../core/components/nfc-input-index.ts | 39 ++ core/static/webpack/types/web-nfc.d.ts | 106 +++++ core/templates/core/widgets/nfc.jinja | 34 +- core/views/forms.py | 7 +- locale/fr/LC_MESSAGES/django.po | 387 +++++++++--------- locale/fr/LC_MESSAGES/djangojs.po | 11 +- 6 files changed, 353 insertions(+), 231 deletions(-) create mode 100644 core/static/webpack/core/components/nfc-input-index.ts create mode 100644 core/static/webpack/types/web-nfc.d.ts diff --git a/core/static/webpack/core/components/nfc-input-index.ts b/core/static/webpack/core/components/nfc-input-index.ts new file mode 100644 index 00000000..4214ba0b --- /dev/null +++ b/core/static/webpack/core/components/nfc-input-index.ts @@ -0,0 +1,39 @@ +import { inheritHtmlElement, registerComponent } from "#core:utils/web-components"; + +@registerComponent("nfc-input") +export class NfcInput extends inheritHtmlElement("input") { + connectedCallback() { + super.connectedCallback(); + + /* Disable feature if browser is not supported or if not HTTPS */ + // biome-ignore lint/correctness/noUndeclaredVariables: browser API + if (typeof NDEFReader === "undefined") { + return; + } + + const button = document.createElement("button"); + const logo = document.createElement("i"); + logo.classList.add("fa-brands", "fa-nfc-symbol"); + button.setAttribute("type", "button"); // Prevent form submission on click + button.appendChild(logo); + button.addEventListener("click", async () => { + // biome-ignore lint/correctness/noUndeclaredVariables: browser API + const ndef = new NDEFReader(); + await ndef.scan(); + ndef.addEventListener("readingerror", () => { + window.alert(gettext("Unsupported NFC card")); + }); + + // biome-ignore lint/correctness/noUndeclaredVariables: browser API + ndef.addEventListener("reading", (event: NDEFReadingEvent) => { + this.node.value = event.serialNumber.replace(/:/g, "").toUpperCase(); + /* Auto submit form, we need another button to not trigger our previously defined click event */ + const submit = document.createElement("button"); + this.node.appendChild(submit); + submit.click(); + submit.remove(); + }); + }); + this.appendChild(button); + } +} diff --git a/core/static/webpack/types/web-nfc.d.ts b/core/static/webpack/types/web-nfc.d.ts new file mode 100644 index 00000000..c647eb55 --- /dev/null +++ b/core/static/webpack/types/web-nfc.d.ts @@ -0,0 +1,106 @@ +// Type definitions for Web NFC +// Project: https://github.com/w3c/web-nfc +// Definitions by: Takefumi Yoshii +// TypeScript Version: 3.9 + +// This type definitions referenced to WebIDL. +// https://w3c.github.io/web-nfc/#actual-idl-index + +// This has been modified to not trigger biome linting + +// biome-ignore lint/correctness/noUnusedVariables: this is the official definition +interface Window { + // biome-ignore lint/style/useNamingConvention: this is the official API name + NDEFMessage: NDEFMessage; +} + +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare class NDEFMessage { + constructor(messageInit: NDEFMessageInit); + records: readonly NDEFRecord[]; +} + +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare interface NDEFMessageInit { + records: NDEFRecordInit[]; +} + +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare type NDEFRecordDataSource = string | BufferSource | NDEFMessageInit; + +// biome-ignore lint/correctness/noUnusedVariables: this is the official definition +interface Window { + // biome-ignore lint/style/useNamingConvention: this is the official API name + NDEFRecord: NDEFRecord; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare class NDEFRecord { + constructor(recordInit: NDEFRecordInit); + readonly recordType: string; + readonly mediaType?: string; + readonly id?: string; + readonly data?: DataView; + readonly encoding?: string; + readonly lang?: string; + toRecords?: () => NDEFRecord[]; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare interface NDEFRecordInit { + recordType: string; + mediaType?: string; + id?: string; + encoding?: string; + lang?: string; + data?: NDEFRecordDataSource; +} + +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare type NDEFMessageSource = string | BufferSource | NDEFMessageInit; + +// biome-ignore lint/correctness/noUnusedVariables: this is the official definition +interface Window { + // biome-ignore lint/style/useNamingConvention: this is the official API name + NDEFReader: NDEFReader; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare class NDEFReader extends EventTarget { + constructor(); + // biome-ignore lint/suspicious/noExplicitAny: who am I to doubt the w3c definitions ? + onreading: (this: this, event: NDEFReadingEvent) => any; + // biome-ignore lint/suspicious/noExplicitAny: who am I to doubt the w3c definitions ? + onreadingerror: (this: this, error: Event) => any; + scan: (options?: NDEFScanOptions) => Promise; + write: (message: NDEFMessageSource, options?: NDEFWriteOptions) => Promise; + makeReadOnly: (options?: NDEFMakeReadOnlyOptions) => Promise; +} + +// biome-ignore lint/correctness/noUnusedVariables: this is the official definition +interface Window { + // biome-ignore lint/style/useNamingConvention: this is the official API name + NDEFReadingEvent: NDEFReadingEvent; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +declare class NDEFReadingEvent extends Event { + constructor(type: string, readingEventInitDict: NDEFReadingEventInit); + serialNumber: string; + message: NDEFMessage; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +interface NDEFReadingEventInit extends EventInit { + serialNumber?: string; + message: NDEFMessageInit; +} + +// biome-ignore lint/style/useNamingConvention: this is the official API name +interface NDEFWriteOptions { + overwrite?: boolean; + signal?: AbortSignal; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +interface NDEFMakeReadOnlyOptions { + signal?: AbortSignal; +} +// biome-ignore lint/style/useNamingConvention: this is the official API name +interface NDEFScanOptions { + signal: AbortSignal; +} diff --git a/core/templates/core/widgets/nfc.jinja b/core/templates/core/widgets/nfc.jinja index 7cfa7249..e0f341b0 100644 --- a/core/templates/core/widgets/nfc.jinja +++ b/core/templates/core/widgets/nfc.jinja @@ -1,33 +1,5 @@ + + - - - + - \ No newline at end of file diff --git a/core/views/forms.py b/core/views/forms.py index cfd1b92c..00b1f359 100644 --- a/core/views/forms.py +++ b/core/views/forms.py @@ -27,6 +27,9 @@ from captcha.fields import CaptchaField from django import forms from django.conf import settings from django.contrib.auth.forms import AuthenticationForm, UserCreationForm +from django.contrib.staticfiles.management.commands.collectstatic import ( + staticfiles_storage, +) from django.core.exceptions import ValidationError from django.db import transaction from django.forms import ( @@ -72,7 +75,9 @@ class NFCTextInput(TextInput): def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) - context["translations"] = {"unsupported": _("Unsupported NFC card")} + context["statics"] = { + "js": staticfiles_storage.url("webpack/core/components/nfc-input-index.ts") + } return context diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index c932c8c3..d357d31c 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: 2024-11-10 15:57+0100\n" +"POT-Creation-Date: 2024-11-14 10:26+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Maréchal \n" @@ -18,8 +18,8 @@ msgstr "" #: accounting/models.py:62 accounting/models.py:101 accounting/models.py:132 #: accounting/models.py:190 club/models.py:55 com/models.py:274 -#: com/models.py:293 counter/models.py:265 counter/models.py:296 -#: counter/models.py:449 forum/models.py:60 launderette/models.py:29 +#: com/models.py:293 counter/models.py:289 counter/models.py:320 +#: counter/models.py:473 forum/models.py:60 launderette/models.py:29 #: launderette/models.py:80 launderette/models.py:116 msgid "name" msgstr "nom" @@ -65,8 +65,8 @@ msgid "account number" msgstr "numéro de compte" #: accounting/models.py:107 accounting/models.py:136 club/models.py:345 -#: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:319 -#: counter/models.py:451 trombi/models.py:209 +#: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:343 +#: counter/models.py:475 trombi/models.py:209 msgid "club" msgstr "club" @@ -87,12 +87,12 @@ msgstr "Compte club" msgid "%(club_account)s on %(bank_account)s" msgstr "%(club_account)s sur %(bank_account)s" -#: accounting/models.py:188 club/models.py:351 counter/models.py:929 +#: accounting/models.py:188 club/models.py:351 counter/models.py:953 #: election/models.py:16 launderette/models.py:165 msgid "start date" msgstr "date de début" -#: accounting/models.py:189 club/models.py:352 counter/models.py:930 +#: accounting/models.py:189 club/models.py:352 counter/models.py:954 #: election/models.py:17 msgid "end date" msgstr "date de fin" @@ -105,8 +105,8 @@ msgstr "est fermé" msgid "club account" msgstr "compte club" -#: accounting/models.py:199 accounting/models.py:255 counter/models.py:57 -#: counter/models.py:647 +#: accounting/models.py:199 accounting/models.py:255 counter/models.py:91 +#: counter/models.py:671 msgid "amount" msgstr "montant" @@ -128,18 +128,18 @@ msgstr "classeur" #: accounting/models.py:256 core/models.py:945 core/models.py:1456 #: core/models.py:1501 core/models.py:1530 core/models.py:1554 -#: counter/models.py:657 counter/models.py:761 counter/models.py:965 +#: counter/models.py:681 counter/models.py:785 counter/models.py:989 #: eboutic/models.py:57 eboutic/models.py:193 forum/models.py:312 #: forum/models.py:413 msgid "date" msgstr "date" -#: accounting/models.py:257 counter/models.py:267 counter/models.py:966 +#: accounting/models.py:257 counter/models.py:291 counter/models.py:990 #: pedagogy/models.py:208 msgid "comment" msgstr "commentaire" -#: accounting/models.py:259 counter/models.py:659 counter/models.py:763 +#: accounting/models.py:259 counter/models.py:683 counter/models.py:787 #: subscription/models.py:56 msgid "payment method" msgstr "méthode de paiement" @@ -166,7 +166,7 @@ msgstr "type comptable" #: accounting/models.py:294 accounting/models.py:429 accounting/models.py:460 #: accounting/models.py:492 core/models.py:1529 core/models.py:1555 -#: counter/models.py:727 +#: counter/models.py:751 msgid "label" msgstr "étiquette" @@ -210,7 +210,7 @@ msgstr "Utilisateur" msgid "Club" msgstr "Club" -#: accounting/models.py:305 core/views/user.py:284 +#: accounting/models.py:305 core/views/user.py:283 msgid "Account" msgstr "Compte" @@ -264,7 +264,7 @@ msgstr "" "Vous devez fournir soit un type comptable simplifié ou un type comptable " "standard" -#: accounting/models.py:421 counter/models.py:306 pedagogy/models.py:41 +#: accounting/models.py:421 counter/models.py:330 pedagogy/models.py:41 msgid "code" msgstr "code" @@ -360,7 +360,7 @@ msgstr "Compte en banque : " #: com/templates/com/screen_edit.jinja:16 com/templates/com/weekmail.jinja:33 #: com/templates/com/weekmail.jinja:62 core/templates/core/file_detail.jinja:25 #: core/templates/core/file_detail.jinja:62 -#: core/templates/core/file_moderation.jinja:24 +#: core/templates/core/file_moderation.jinja:48 #: core/templates/core/group_detail.jinja:26 #: core/templates/core/group_list.jinja:25 core/templates/core/macros.jinja:96 #: core/templates/core/macros.jinja:115 core/templates/core/page_prop.jinja:14 @@ -385,7 +385,7 @@ msgid "Delete" msgstr "Supprimer" #: accounting/templates/accounting/bank_account_details.jinja:18 -#: club/views.py:79 core/views/user.py:202 sas/templates/sas/picture.jinja:91 +#: club/views.py:79 core/views/user.py:201 sas/templates/sas/picture.jinja:91 msgid "Infos" msgstr "Infos" @@ -416,10 +416,10 @@ msgstr "Nouveau compte club" #: com/templates/com/poster_list.jinja:43 #: com/templates/com/poster_list.jinja:45 #: com/templates/com/screen_list.jinja:26 com/templates/com/weekmail.jinja:32 -#: com/templates/com/weekmail.jinja:61 core/templates/core/file.jinja:38 +#: com/templates/com/weekmail.jinja:61 core/templates/core/file.jinja:42 #: core/templates/core/group_list.jinja:24 core/templates/core/page.jinja:35 #: core/templates/core/poster_list.jinja:40 -#: core/templates/core/user_tools.jinja:71 core/views/user.py:232 +#: core/templates/core/user_tools.jinja:71 core/views/user.py:231 #: counter/templates/counter/cash_summary_list.jinja:53 #: counter/templates/counter/counter_list.jinja:17 #: counter/templates/counter/counter_list.jinja:33 @@ -556,7 +556,7 @@ msgstr "Non" #: com/templates/com/news_admin_list.jinja:231 #: com/templates/com/news_admin_list.jinja:272 #: com/templates/com/news_admin_list.jinja:307 -#: core/templates/core/file.jinja:36 core/templates/core/page.jinja:31 +#: core/templates/core/file.jinja:40 core/templates/core/page.jinja:31 msgid "View" msgstr "Voir" @@ -1041,7 +1041,7 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs" msgid "A club with that unix_name already exists" msgstr "Un club avec ce nom UNIX existe déjà." -#: club/models.py:337 counter/models.py:920 counter/models.py:956 +#: club/models.py:337 counter/models.py:944 counter/models.py:980 #: eboutic/models.py:53 eboutic/models.py:189 election/models.py:183 #: launderette/models.py:130 launderette/models.py:184 sas/models.py:273 #: trombi/models.py:205 @@ -1053,8 +1053,8 @@ msgstr "nom d'utilisateur" msgid "role" msgstr "rôle" -#: club/models.py:359 core/models.py:89 counter/models.py:266 -#: counter/models.py:297 election/models.py:13 election/models.py:115 +#: club/models.py:359 core/models.py:89 counter/models.py:290 +#: counter/models.py:321 election/models.py:13 election/models.py:115 #: election/models.py:188 forum/models.py:61 forum/models.py:245 msgid "description" msgstr "description" @@ -1146,7 +1146,7 @@ msgid "There are no members in this club." msgstr "Il n'y a pas de membres dans ce club." #: club/templates/club/club_members.jinja:80 -#: core/templates/core/file_detail.jinja:19 core/views/forms.py:301 +#: core/templates/core/file_detail.jinja:19 core/views/forms.py:308 #: launderette/views.py:210 trombi/templates/trombi/detail.jinja:19 msgid "Add" msgstr "Ajouter" @@ -1369,8 +1369,9 @@ msgstr "Anciens membres" msgid "History" msgstr "Historique" -#: club/views.py:116 core/templates/core/base.jinja:106 core/views/user.py:225 -#: sas/templates/sas/picture.jinja:110 trombi/views.py:62 +#: club/views.py:116 core/templates/core/base/header.jinja:61 +#: core/views/user.py:224 sas/templates/sas/picture.jinja:110 +#: trombi/views.py:62 msgid "Tools" msgstr "Outils" @@ -1512,7 +1513,7 @@ msgstr "Administration des mailing listes" #: com/templates/com/news_admin_list.jinja:309 #: com/templates/com/news_detail.jinja:39 #: core/templates/core/file_detail.jinja:65 -#: core/templates/core/file_moderation.jinja:23 +#: core/templates/core/file_moderation.jinja:42 #: sas/templates/sas/moderation.jinja:17 sas/templates/sas/picture.jinja:68 msgid "Moderate" msgstr "Modérer" @@ -1655,7 +1656,7 @@ msgid "Calls to moderate" msgstr "Appels à modérer" #: com/templates/com/news_admin_list.jinja:242 -#: core/templates/core/base.jinja:221 +#: core/templates/core/base/navbar.jinja:14 msgid "Events" msgstr "Événements" @@ -2392,18 +2393,44 @@ msgstr "500, Erreur Serveur" msgid "Welcome!" msgstr "Bienvenue !" -#: core/templates/core/base.jinja:58 core/templates/core/login.jinja:8 -#: core/templates/core/login.jinja:18 core/templates/core/login.jinja:51 +#: core/templates/core/base.jinja:104 core/templates/core/base/navbar.jinja:43 +msgid "Contacts" +msgstr "Contacts" + +#: core/templates/core/base.jinja:105 +msgid "Legal notices" +msgstr "Mentions légales" + +#: core/templates/core/base.jinja:106 +msgid "Intellectual property" +msgstr "Propriété intellectuelle" + +#: core/templates/core/base.jinja:107 +msgid "Help & Documentation" +msgstr "Aide & Documentation" + +#: core/templates/core/base.jinja:108 +msgid "R&D" +msgstr "R&D" + +#: core/templates/core/base.jinja:111 +msgid "Site created by the IT Department of the AE" +msgstr "Site réalisé par le Pôle Informatique de l'AE" + +#: core/templates/core/base/header.jinja:13 core/templates/core/login.jinja:8 +#: core/templates/core/login.jinja:18 core/templates/core/login.jinja:50 #: core/templates/core/password_reset_complete.jinja:5 msgid "Login" msgstr "Connexion" -#: core/templates/core/base.jinja:59 core/templates/core/register.jinja:7 -#: core/templates/core/register.jinja:16 core/templates/core/register.jinja:22 +#: core/templates/core/base/header.jinja:14 +#: core/templates/core/register.jinja:7 core/templates/core/register.jinja:16 +#: core/templates/core/register.jinja:22 msgid "Register" msgstr "Inscription" -#: core/templates/core/base.jinja:65 core/templates/core/base.jinja:66 +#: core/templates/core/base/header.jinja:20 +#: core/templates/core/base/header.jinja:21 #: forum/templates/forum/macros.jinja:179 #: forum/templates/forum/macros.jinja:183 #: matmat/templates/matmat/search_form.jinja:39 @@ -2412,52 +2439,53 @@ msgstr "Inscription" msgid "Search" msgstr "Recherche" -#: core/templates/core/base.jinja:107 +#: core/templates/core/base/header.jinja:62 msgid "Logout" msgstr "Déconnexion" -#: core/templates/core/base.jinja:155 +#: core/templates/core/base/header.jinja:110 msgid "You do not have any unread notification" msgstr "Vous n'avez aucune notification non lue" -#: core/templates/core/base.jinja:160 +#: core/templates/core/base/header.jinja:115 msgid "View more" msgstr "Voir plus" -#: core/templates/core/base.jinja:163 +#: core/templates/core/base/header.jinja:118 #: forum/templates/forum/last_unread.jinja:21 msgid "Mark all as read" msgstr "Marquer tout comme lu" -#: core/templates/core/base.jinja:211 +#: core/templates/core/base/navbar.jinja:4 msgid "Main" msgstr "Accueil" -#: core/templates/core/base.jinja:213 +#: core/templates/core/base/navbar.jinja:6 msgid "Associations & Clubs" msgstr "Associations & Clubs" -#: core/templates/core/base.jinja:215 +#: core/templates/core/base/navbar.jinja:8 msgid "AE" msgstr "L'AE" -#: core/templates/core/base.jinja:216 +#: core/templates/core/base/navbar.jinja:9 msgid "AE's clubs" msgstr "Les clubs de L'AE" -#: core/templates/core/base.jinja:217 +#: core/templates/core/base/navbar.jinja:10 msgid "Others UTBM's Associations" msgstr "Les autres associations de l'UTBM" -#: core/templates/core/base.jinja:223 core/templates/core/user_tools.jinja:172 +#: core/templates/core/base/navbar.jinja:16 +#: core/templates/core/user_tools.jinja:172 msgid "Elections" msgstr "Élections" -#: core/templates/core/base.jinja:224 +#: core/templates/core/base/navbar.jinja:17 msgid "Big event" msgstr "Grandes Activités" -#: core/templates/core/base.jinja:227 +#: core/templates/core/base/navbar.jinja:20 #: forum/templates/forum/favorite_topics.jinja:18 #: forum/templates/forum/last_unread.jinja:18 #: forum/templates/forum/macros.jinja:90 forum/templates/forum/main.jinja:6 @@ -2466,11 +2494,11 @@ msgstr "Grandes Activités" msgid "Forum" msgstr "Forum" -#: core/templates/core/base.jinja:228 +#: core/templates/core/base/navbar.jinja:21 msgid "Gallery" msgstr "Photos" -#: core/templates/core/base.jinja:229 counter/models.py:459 +#: core/templates/core/base/navbar.jinja:22 counter/models.py:483 #: counter/templates/counter/counter_list.jinja:11 #: eboutic/templates/eboutic/eboutic_main.jinja:4 #: eboutic/templates/eboutic/eboutic_main.jinja:22 @@ -2480,78 +2508,55 @@ msgstr "Photos" msgid "Eboutic" msgstr "Eboutic" -#: core/templates/core/base.jinja:231 +#: core/templates/core/base/navbar.jinja:24 msgid "Services" msgstr "Services" -#: core/templates/core/base.jinja:233 +#: core/templates/core/base/navbar.jinja:26 msgid "Matmatronch" msgstr "Matmatronch" -#: core/templates/core/base.jinja:234 launderette/models.py:38 +#: core/templates/core/base/navbar.jinja:27 launderette/models.py:38 #: launderette/templates/launderette/launderette_book.jinja:5 #: launderette/templates/launderette/launderette_book_choose.jinja:4 #: launderette/templates/launderette/launderette_main.jinja:4 msgid "Launderette" msgstr "Laverie" -#: core/templates/core/base.jinja:235 core/templates/core/file.jinja:20 -#: core/views/files.py:120 +#: core/templates/core/base/navbar.jinja:28 core/templates/core/file.jinja:24 +#: core/views/files.py:121 msgid "Files" msgstr "Fichiers" -#: core/templates/core/base.jinja:236 core/templates/core/user_tools.jinja:163 +#: core/templates/core/base/navbar.jinja:29 +#: core/templates/core/user_tools.jinja:163 msgid "Pedagogy" msgstr "Pédagogie" -#: core/templates/core/base.jinja:240 +#: core/templates/core/base/navbar.jinja:33 msgid "My Benefits" msgstr "Mes Avantages" -#: core/templates/core/base.jinja:242 +#: core/templates/core/base/navbar.jinja:35 msgid "Sponsors" msgstr "Partenaires" -#: core/templates/core/base.jinja:243 +#: core/templates/core/base/navbar.jinja:36 msgid "Subscriber benefits" msgstr "Les avantages cotisants" -#: core/templates/core/base.jinja:247 +#: core/templates/core/base/navbar.jinja:40 msgid "Help" msgstr "Aide" -#: core/templates/core/base.jinja:249 +#: core/templates/core/base/navbar.jinja:42 msgid "FAQ" msgstr "FAQ" -#: core/templates/core/base.jinja:250 core/templates/core/base.jinja:290 -msgid "Contacts" -msgstr "Contacts" - -#: core/templates/core/base.jinja:251 +#: core/templates/core/base/navbar.jinja:44 msgid "Wiki" msgstr "Wiki" -#: core/templates/core/base.jinja:291 -msgid "Legal notices" -msgstr "Mentions légales" - -#: core/templates/core/base.jinja:292 -msgid "Intellectual property" -msgstr "Propriété intellectuelle" - -#: core/templates/core/base.jinja:293 -msgid "Help & Documentation" -msgstr "Aide & Documentation" - -#: core/templates/core/base.jinja:294 -msgid "R&D" -msgstr "R&D" - -#: core/templates/core/base.jinja:297 -msgid "Site created by the IT Department of the AE" -msgstr "Site réalisé par le Pôle Informatique de l'AE" - #: core/templates/core/create.jinja:4 core/templates/core/create.jinja:8 #, python-format msgid "Create %(name)s" @@ -2560,23 +2565,23 @@ msgstr "Créer %(name)s" #: core/templates/core/delete_confirm.jinja:4 #: core/templates/core/delete_confirm.jinja:14 #: core/templates/core/file_delete_confirm.jinja:4 -#: core/templates/core/file_delete_confirm.jinja:8 +#: core/templates/core/file_delete_confirm.jinja:18 msgid "Delete confirmation" msgstr "Confirmation de suppression" #: core/templates/core/delete_confirm.jinja:16 -#: core/templates/core/file_delete_confirm.jinja:10 +#: core/templates/core/file_delete_confirm.jinja:29 #, python-format msgid "Are you sure you want to delete \"%(obj)s\"?" msgstr "Êtes-vous sûr de vouloir supprimer \"%(obj)s\" ?" #: core/templates/core/delete_confirm.jinja:17 -#: core/templates/core/file_delete_confirm.jinja:11 +#: core/templates/core/file_delete_confirm.jinja:36 msgid "Confirm" msgstr "Confirmation" #: core/templates/core/delete_confirm.jinja:20 -#: core/templates/core/file_delete_confirm.jinja:14 +#: core/templates/core/file_delete_confirm.jinja:46 #: counter/templates/counter/counter_click.jinja:121 #: sas/templates/sas/ask_picture_removal.jinja:20 msgid "Cancel" @@ -2589,28 +2594,28 @@ msgstr "Annuler" msgid "Edit %(obj)s" msgstr "Éditer %(obj)s" -#: core/templates/core/file.jinja:7 core/templates/core/file_list.jinja:6 +#: core/templates/core/file.jinja:11 core/templates/core/file_list.jinja:6 msgid "File list" msgstr "Liste de fichiers" -#: core/templates/core/file.jinja:9 +#: core/templates/core/file.jinja:13 msgid "New file" msgstr "Nouveau fichier" -#: core/templates/core/file.jinja:11 core/templates/core/page.jinja:11 +#: core/templates/core/file.jinja:15 core/templates/core/page.jinja:11 msgid "Not found" msgstr "Non trouvé" -#: core/templates/core/file.jinja:32 +#: core/templates/core/file.jinja:36 msgid "My files" msgstr "Mes fichiers" -#: core/templates/core/file.jinja:41 core/templates/core/page.jinja:38 +#: core/templates/core/file.jinja:45 core/templates/core/page.jinja:38 msgid "Prop" msgstr "Propriétés" #: core/templates/core/file_detail.jinja:13 -#: core/templates/core/file_moderation.jinja:20 +#: core/templates/core/file_moderation.jinja:35 #: sas/templates/sas/picture.jinja:103 msgid "Owner: " msgstr "Propriétaire : " @@ -2638,7 +2643,7 @@ msgid "Real name: " msgstr "Nom réel : " #: core/templates/core/file_detail.jinja:54 -#: core/templates/core/file_moderation.jinja:21 +#: core/templates/core/file_moderation.jinja:36 #: sas/templates/sas/picture.jinja:94 msgid "Date: " msgstr "Date : " @@ -2663,12 +2668,12 @@ msgstr "Télécharger" msgid "There is no file in this website." msgstr "Il n'y a pas de fichier sur ce site web." -#: core/templates/core/file_moderation.jinja:4 -#: core/templates/core/file_moderation.jinja:8 +#: core/templates/core/file_moderation.jinja:16 +#: core/templates/core/file_moderation.jinja:20 msgid "File moderation" msgstr "Modération des fichiers" -#: core/templates/core/file_moderation.jinja:19 +#: core/templates/core/file_moderation.jinja:34 msgid "Full name: " msgstr "Nom complet : " @@ -2731,11 +2736,11 @@ msgstr "" "Votre nom d'utilisateur et votre mot de passe ne correspondent pas. Merci de " "réessayer." -#: core/templates/core/login.jinja:56 +#: core/templates/core/login.jinja:55 msgid "Lost password?" msgstr "Mot de passe perdu ?" -#: core/templates/core/login.jinja:58 +#: core/templates/core/login.jinja:57 msgid "Create account" msgstr "Créer un compte" @@ -2765,11 +2770,11 @@ msgstr "Créneau" msgid "Tokens" msgstr "Jetons" -#: core/templates/core/macros.jinja:213 +#: core/templates/core/macros.jinja:258 msgid "Select All" msgstr "Tout sélectionner" -#: core/templates/core/macros.jinja:214 +#: core/templates/core/macros.jinja:259 msgid "Unselect All" msgstr "Tout désélectionner" @@ -2995,7 +3000,7 @@ msgstr "Résultat de la recherche" msgid "Users" msgstr "Utilisateurs" -#: core/templates/core/search.jinja:20 core/views/user.py:247 +#: core/templates/core/search.jinja:20 core/views/user.py:246 msgid "Clubs" msgstr "Clubs" @@ -3040,7 +3045,7 @@ msgstr "Facture eboutic" msgid "Etickets" msgstr "Etickets" -#: core/templates/core/user_account.jinja:69 core/views/user.py:639 +#: core/templates/core/user_account.jinja:69 core/views/user.py:638 msgid "User has no account" msgstr "L'utilisateur n'a pas de compte" @@ -3268,7 +3273,7 @@ msgid "To be moderated" msgstr "A modérer" #: core/templates/core/user_preferences.jinja:8 -#: core/templates/core/user_preferences.jinja:13 core/views/user.py:239 +#: core/templates/core/user_preferences.jinja:13 core/views/user.py:238 msgid "Preferences" msgstr "Préférences" @@ -3343,7 +3348,7 @@ msgstr "Outils utilisateurs" msgid "Sith management" msgstr "Gestion de Sith" -#: core/templates/core/user_tools.jinja:21 core/views/user.py:255 +#: core/templates/core/user_tools.jinja:21 core/views/user.py:254 msgid "Groups" msgstr "Groupes" @@ -3398,7 +3403,7 @@ msgstr "Relevés de caisse" msgid "Invoices call" msgstr "Appels à facture" -#: core/templates/core/user_tools.jinja:72 core/views/user.py:277 +#: core/templates/core/user_tools.jinja:72 core/views/user.py:276 #: counter/templates/counter/counter_list.jinja:18 #: counter/templates/counter/counter_list.jinja:34 #: counter/templates/counter/counter_list.jinja:50 @@ -3483,42 +3488,38 @@ msgid_plural "%(nb_days)d days, %(remainder)s" msgstr[0] "" msgstr[1] "" -#: core/views/files.py:117 +#: core/views/files.py:118 msgid "Add a new folder" msgstr "Ajouter un nouveau dossier" -#: core/views/files.py:137 +#: core/views/files.py:138 #, python-format msgid "Error creating folder %(folder_name)s: %(msg)s" msgstr "Erreur de création du dossier %(folder_name)s : %(msg)s" -#: core/views/files.py:157 core/views/forms.py:266 core/views/forms.py:273 +#: core/views/files.py:158 core/views/forms.py:273 core/views/forms.py:280 #: sas/forms.py:60 #, python-format msgid "Error uploading file %(file_name)s: %(msg)s" msgstr "Erreur d'envoi du fichier %(file_name)s : %(msg)s" -#: core/views/files.py:231 sas/forms.py:83 +#: core/views/files.py:232 sas/forms.py:83 msgid "Apply rights recursively" msgstr "Appliquer les droits récursivement" -#: core/views/forms.py:75 -msgid "Unsupported NFC card" -msgstr "Carte NFC non supportée" - -#: core/views/forms.py:89 core/views/forms.py:97 +#: core/views/forms.py:96 core/views/forms.py:104 msgid "Choose file" msgstr "Choisir un fichier" -#: core/views/forms.py:113 core/views/forms.py:121 +#: core/views/forms.py:120 core/views/forms.py:128 msgid "Choose user" msgstr "Choisir un utilisateur" -#: core/views/forms.py:153 +#: core/views/forms.py:160 msgid "Username, email, or account number" msgstr "Nom d'utilisateur, email, ou numéro de compte AE" -#: core/views/forms.py:216 +#: core/views/forms.py:223 msgid "" "Profile: you need to be visible on the picture, in order to be recognized (e." "g. by the barmen)" @@ -3526,44 +3527,44 @@ msgstr "" "Photo de profil: vous devez être visible sur la photo afin d'être reconnu " "(par exemple par les barmen)" -#: core/views/forms.py:221 +#: core/views/forms.py:228 msgid "Avatar: used on the forum" msgstr "Avatar : utilisé sur le forum" -#: core/views/forms.py:225 +#: core/views/forms.py:232 msgid "Scrub: let other know how your scrub looks like!" msgstr "Blouse : montrez aux autres à quoi ressemble votre blouse !" -#: core/views/forms.py:277 +#: core/views/forms.py:284 msgid "Bad image format, only jpeg, png, webp and gif are accepted" msgstr "Mauvais format d'image, seuls les jpeg, png, webp et gif sont acceptés" -#: core/views/forms.py:298 +#: core/views/forms.py:305 msgid "Godfather / Godmother" msgstr "Parrain / Marraine" -#: core/views/forms.py:299 +#: core/views/forms.py:306 msgid "Godchild" msgstr "Fillot / Fillote" -#: core/views/forms.py:304 counter/forms.py:82 trombi/views.py:151 +#: core/views/forms.py:311 counter/forms.py:82 trombi/views.py:151 msgid "Select user" msgstr "Choisir un utilisateur" -#: core/views/forms.py:318 +#: core/views/forms.py:325 msgid "This user does not exist" msgstr "Cet utilisateur n'existe pas" -#: core/views/forms.py:320 +#: core/views/forms.py:327 msgid "You cannot be related to yourself" msgstr "Vous ne pouvez pas être relié à vous-même" -#: core/views/forms.py:332 +#: core/views/forms.py:339 #, python-format msgid "%s is already your godfather" msgstr "%s est déjà votre parrain/marraine" -#: core/views/forms.py:338 +#: core/views/forms.py:345 #, python-format msgid "%s is already your godchild" msgstr "%s est déjà votre fillot/fillote" @@ -3576,26 +3577,26 @@ msgstr "Utilisateurs à ajouter au groupe" msgid "Users to remove from group" msgstr "Utilisateurs à retirer du groupe" -#: core/views/user.py:184 +#: core/views/user.py:183 msgid "We couldn't verify that this email actually exists" msgstr "Nous n'avons pas réussi à vérifier que cette adresse mail existe." -#: core/views/user.py:207 +#: core/views/user.py:206 msgid "Family" msgstr "Famille" -#: core/views/user.py:212 sas/templates/sas/album.jinja:67 +#: core/views/user.py:211 sas/templates/sas/album.jinja:67 #: trombi/templates/trombi/export.jinja:25 #: trombi/templates/trombi/user_profile.jinja:11 msgid "Pictures" msgstr "Photos" -#: core/views/user.py:220 +#: core/views/user.py:219 msgid "Galaxy" msgstr "Galaxie" -#: counter/apps.py:30 counter/models.py:475 counter/models.py:926 -#: counter/models.py:962 launderette/models.py:32 +#: counter/apps.py:30 counter/models.py:499 counter/models.py:950 +#: counter/models.py:986 launderette/models.py:32 msgid "counter" msgstr "comptoir" @@ -3615,181 +3616,181 @@ msgstr "Vidange de votre compte AE" msgid "Ecocup regularization" msgstr "Régularization des ecocups" -#: counter/models.py:56 +#: counter/models.py:90 msgid "account id" msgstr "numéro de compte" -#: counter/models.py:58 +#: counter/models.py:92 msgid "recorded product" msgstr "produits consignés" -#: counter/models.py:61 +#: counter/models.py:97 msgid "customer" msgstr "client" -#: counter/models.py:62 +#: counter/models.py:98 msgid "customers" msgstr "clients" -#: counter/models.py:74 counter/views.py:261 +#: counter/models.py:110 counter/views.py:261 msgid "Not enough money" msgstr "Solde insuffisant" -#: counter/models.py:172 +#: counter/models.py:196 msgid "First name" msgstr "Prénom" -#: counter/models.py:173 +#: counter/models.py:197 msgid "Last name" msgstr "Nom de famille" -#: counter/models.py:174 +#: counter/models.py:198 msgid "Address 1" msgstr "Adresse 1" -#: counter/models.py:175 +#: counter/models.py:199 msgid "Address 2" msgstr "Adresse 2" -#: counter/models.py:176 +#: counter/models.py:200 msgid "Zip code" msgstr "Code postal" -#: counter/models.py:177 +#: counter/models.py:201 msgid "City" msgstr "Ville" -#: counter/models.py:178 +#: counter/models.py:202 msgid "Country" msgstr "Pays" -#: counter/models.py:186 +#: counter/models.py:210 msgid "Phone number" msgstr "Numéro de téléphone" -#: counter/models.py:228 +#: counter/models.py:252 msgid "When the mail warning that the account was about to be dumped was sent." msgstr "Quand le mail d'avertissement de la vidange du compte a été envoyé." -#: counter/models.py:233 +#: counter/models.py:257 msgid "Set this to True if the warning mail received an error" msgstr "Mettre à True si le mail a reçu une erreur" -#: counter/models.py:240 +#: counter/models.py:264 msgid "The operation that emptied the account." msgstr "L'opération qui a vidé le compte." -#: counter/models.py:277 counter/models.py:301 +#: counter/models.py:301 counter/models.py:325 msgid "product type" msgstr "type du produit" -#: counter/models.py:307 +#: counter/models.py:331 msgid "purchase price" msgstr "prix d'achat" -#: counter/models.py:308 +#: counter/models.py:332 msgid "selling price" msgstr "prix de vente" -#: counter/models.py:309 +#: counter/models.py:333 msgid "special selling price" msgstr "prix de vente spécial" -#: counter/models.py:316 +#: counter/models.py:340 msgid "icon" msgstr "icône" -#: counter/models.py:321 +#: counter/models.py:345 msgid "limit age" msgstr "âge limite" -#: counter/models.py:322 +#: counter/models.py:346 msgid "tray price" msgstr "prix plateau" -#: counter/models.py:326 +#: counter/models.py:350 msgid "parent product" msgstr "produit parent" -#: counter/models.py:332 +#: counter/models.py:356 msgid "buying groups" msgstr "groupe d'achat" -#: counter/models.py:334 election/models.py:50 +#: counter/models.py:358 election/models.py:50 msgid "archived" msgstr "archivé" -#: counter/models.py:337 counter/models.py:1060 +#: counter/models.py:361 counter/models.py:1084 msgid "product" msgstr "produit" -#: counter/models.py:454 +#: counter/models.py:478 msgid "products" msgstr "produits" -#: counter/models.py:457 +#: counter/models.py:481 msgid "counter type" msgstr "type de comptoir" -#: counter/models.py:459 +#: counter/models.py:483 msgid "Bar" msgstr "Bar" -#: counter/models.py:459 +#: counter/models.py:483 msgid "Office" msgstr "Bureau" -#: counter/models.py:462 +#: counter/models.py:486 msgid "sellers" msgstr "vendeurs" -#: counter/models.py:470 launderette/models.py:178 +#: counter/models.py:494 launderette/models.py:178 msgid "token" msgstr "jeton" -#: counter/models.py:665 +#: counter/models.py:689 msgid "bank" msgstr "banque" -#: counter/models.py:667 counter/models.py:768 +#: counter/models.py:691 counter/models.py:792 msgid "is validated" msgstr "est validé" -#: counter/models.py:672 +#: counter/models.py:696 msgid "refilling" msgstr "rechargement" -#: counter/models.py:745 eboutic/models.py:249 +#: counter/models.py:769 eboutic/models.py:249 msgid "unit price" msgstr "prix unitaire" -#: counter/models.py:746 counter/models.py:1040 eboutic/models.py:250 +#: counter/models.py:770 counter/models.py:1064 eboutic/models.py:250 msgid "quantity" msgstr "quantité" -#: counter/models.py:765 +#: counter/models.py:789 msgid "Sith account" msgstr "Compte utilisateur" -#: counter/models.py:765 sith/settings.py:411 sith/settings.py:416 +#: counter/models.py:789 sith/settings.py:411 sith/settings.py:416 #: sith/settings.py:436 msgid "Credit card" msgstr "Carte bancaire" -#: counter/models.py:773 +#: counter/models.py:797 msgid "selling" msgstr "vente" -#: counter/models.py:877 +#: counter/models.py:901 msgid "Unknown event" msgstr "Événement inconnu" -#: counter/models.py:878 +#: counter/models.py:902 #, python-format msgid "Eticket bought for the event %(event)s" msgstr "Eticket acheté pour l'événement %(event)s" -#: counter/models.py:880 counter/models.py:893 +#: counter/models.py:904 counter/models.py:917 #, python-format msgid "" "You bought an eticket for the event %(event)s.\n" @@ -3801,63 +3802,63 @@ msgstr "" "Vous pouvez également retrouver tous vos e-tickets sur votre page de compte " "%(url)s." -#: counter/models.py:931 +#: counter/models.py:955 msgid "last activity date" msgstr "dernière activité" -#: counter/models.py:934 +#: counter/models.py:958 msgid "permanency" msgstr "permanence" -#: counter/models.py:967 +#: counter/models.py:991 msgid "emptied" msgstr "coffre vidée" -#: counter/models.py:970 +#: counter/models.py:994 msgid "cash register summary" msgstr "relevé de caisse" -#: counter/models.py:1036 +#: counter/models.py:1060 msgid "cash summary" msgstr "relevé" -#: counter/models.py:1039 +#: counter/models.py:1063 msgid "value" msgstr "valeur" -#: counter/models.py:1042 +#: counter/models.py:1066 msgid "check" msgstr "chèque" -#: counter/models.py:1044 +#: counter/models.py:1068 msgid "True if this is a bank check, else False" msgstr "Vrai si c'est un chèque, sinon Faux." -#: counter/models.py:1048 +#: counter/models.py:1072 msgid "cash register summary item" msgstr "élément de relevé de caisse" -#: counter/models.py:1064 +#: counter/models.py:1088 msgid "banner" msgstr "bannière" -#: counter/models.py:1066 +#: counter/models.py:1090 msgid "event date" msgstr "date de l'événement" -#: counter/models.py:1068 +#: counter/models.py:1092 msgid "event title" msgstr "titre de l'événement" -#: counter/models.py:1070 +#: counter/models.py:1094 msgid "secret" msgstr "secret" -#: counter/models.py:1109 +#: counter/models.py:1133 msgid "uid" msgstr "uid" -#: counter/models.py:1114 +#: counter/models.py:1138 msgid "student cards" msgstr "cartes étudiante" diff --git a/locale/fr/LC_MESSAGES/djangojs.po b/locale/fr/LC_MESSAGES/djangojs.po index 3c93fbb7..e907e571 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: 2024-11-10 16:00+0100\n" +"POT-Creation-Date: 2024-11-14 10:24+0100\n" "PO-Revision-Date: 2024-09-17 11:54+0200\n" "Last-Translator: Sli \n" "Language-Team: AE info \n" @@ -23,17 +23,14 @@ msgid "captured.%s" msgstr "capture.%s" #: core/static/webpack/core/components/ajax-select-base.ts:68 -#: staticfiles/generated/webpack/core/static/webpack/core/components/ajax-select-base.js:57 msgid "Remove" msgstr "Retirer" #: core/static/webpack/core/components/ajax-select-base.ts:88 -#: staticfiles/generated/webpack/core/static/webpack/core/components/ajax-select-base.js:77 msgid "You need to type %(number)s more characters" msgstr "Vous devez taper %(number)s caractères de plus" #: core/static/webpack/core/components/ajax-select-base.ts:92 -#: staticfiles/generated/webpack/core/static/webpack/core/components/ajax-select-base.js:81 msgid "No results found" msgstr "Aucun résultat trouvé" @@ -113,6 +110,10 @@ msgstr "Activer le plein écran" msgid "Markdown guide" msgstr "Guide markdown" +#: core/static/webpack/core/components/nfc-input-index.ts:24 +msgid "Unsupported NFC card" +msgstr "Carte NFC non supportée" + #: core/static/webpack/user/family-graph-index.js:233 msgid "family_tree.%(extension)s" msgstr "arbre_genealogique.%(extension)s" @@ -126,11 +127,9 @@ msgid "Incorrect value" msgstr "Valeur incorrecte" #: sas/static/webpack/sas/viewer-index.ts:271 -#: staticfiles/generated/webpack/sas/static/webpack/sas/viewer-index.js:234 msgid "Couldn't moderate picture" msgstr "Il n'a pas été possible de modérer l'image" #: sas/static/webpack/sas/viewer-index.ts:284 -#: staticfiles/generated/webpack/sas/static/webpack/sas/viewer-index.js:248 msgid "Couldn't delete picture" msgstr "Il n'a pas été possible de supprimer l'image"