8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-22 23:13:46 +00:00

Merge branch 'frontend' into 'dev'

Refactor navbar and general frontend.

See merge request re2o/re2o!569
This commit is contained in:
chirac 2020-11-18 00:33:55 +01:00
commit 368d623271
60 changed files with 3052 additions and 2394 deletions

4
.gitignore vendored
View file

@ -47,3 +47,7 @@ settings_local.py
local_routers.py
re2o.png
media/
# themes
static/css/themes/*
!static/css/themes/default.css

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2019-01-07 01:37+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"

View file

@ -21,9 +21,9 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Last-Translator: Yoann Piétri <me@nanoy.fr>\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -37,7 +37,7 @@ msgstr "Vous n'avez pas le droit de voir cette application."
msgid "Select a payment method"
msgstr "Sélectionnez un moyen de paiement"
#: cotisations/forms.py:73 cotisations/models.py:688
#: cotisations/forms.py:73 cotisations/models.py:695
msgid "Member"
msgstr "Adhérent"
@ -130,48 +130,48 @@ msgstr ""
msgid "date"
msgstr "date"
#: cotisations/models.py:130
#: cotisations/models.py:140
msgid "cheque number"
msgstr "numéro de chèque"
#: cotisations/models.py:133
#: cotisations/models.py:143
msgid "validated"
msgstr "validé"
#: cotisations/models.py:135
#: cotisations/models.py:145
msgid "controlled"
msgstr "contrôlé"
#: cotisations/models.py:141
#: cotisations/models.py:151
msgid "Can edit the \"controlled\" state"
msgstr "Peut modifier l'état \"contrôlé\""
#: cotisations/models.py:142
#: cotisations/models.py:152
msgid "Can view an invoice object"
msgstr "Peut voir un objet facture"
#: cotisations/models.py:143
#: cotisations/models.py:153
msgid "Can edit all the previous invoices"
msgstr "Peut modifier toutes les factures précédentes"
#: cotisations/models.py:145 cotisations/models.py:462 cotisations/views.py:376
#: cotisations/views.py:571
#: cotisations/models.py:155 cotisations/models.py:451 cotisations/views.py:380
#: cotisations/views.py:575
msgid "invoice"
msgstr "facture"
#: cotisations/models.py:146
#: cotisations/models.py:156
msgid "invoices"
msgstr "factures"
#: cotisations/models.py:160
#: cotisations/models.py:170
msgid "You don't have the right to edit an invoice."
msgstr "Vous n'avez pas le droit de modifier une facture."
#: cotisations/models.py:168
#: cotisations/models.py:178
msgid "You don't have the right to edit this user's invoices."
msgstr "Vous n'avez pas le droit de modifier les factures de cet utilisateur."
#: cotisations/models.py:177
#: cotisations/models.py:187
msgid ""
"You don't have the right to edit an invoice already controlled or "
"invalidated."
@ -179,15 +179,15 @@ msgstr ""
"Vous n'avez pas le droit de modifier une facture précédemment contrôlée ou "
"invalidée."
#: cotisations/models.py:192
#: cotisations/models.py:202
msgid "You don't have the right to delete an invoice."
msgstr "Vous n'avez pas le droit de supprimer une facture."
#: cotisations/models.py:200
#: cotisations/models.py:210
msgid "You don't have the right to delete this user's invoices."
msgstr "Vous n'avez pas le droit de supprimer les factures de cet utilisateur."
#: cotisations/models.py:209
#: cotisations/models.py:219
msgid ""
"You don't have the right to delete an invoice already controlled or "
"invalidated."
@ -195,137 +195,123 @@ msgstr ""
"Vous n'avez pas le droit de supprimer une facture précédemment contrôlée ou "
"invalidée."
#: cotisations/models.py:223
#: cotisations/models.py:233
msgid "You don't have the right to view someone else's invoices history."
msgstr ""
"Vous n'avez pas le droit de voir l'historique des factures d'un autre "
"utilisateur."
#: cotisations/models.py:231
#: cotisations/models.py:241
msgid "The invoice has been invalidated."
msgstr "La facture a été invalidée."
#: cotisations/models.py:246
#: cotisations/models.py:256
msgid "You don't have the right to edit the \"controlled\" state."
msgstr "Vous n'avez pas le droit de modifier le statut \"contrôlé\"."
#: cotisations/models.py:265
#: cotisations/models.py:275
msgid "There are no payment methods that you can use."
msgstr "Il n'y a pas de moyens de paiement que vous puissiez utiliser."
#: cotisations/models.py:271
#: cotisations/models.py:281
msgid "There are no articles that you can buy."
msgstr "Il n'y a pas d'articles que vous puissiez acheter."
#: cotisations/models.py:378
#: cotisations/models.py:374
msgid "Can view a custom invoice object"
msgstr "Peut voir un objet facture personnalisée"
#: cotisations/models.py:380
#: cotisations/models.py:376
msgid "recipient"
msgstr "destinataire"
#: cotisations/models.py:381
#: cotisations/models.py:377
msgid "payment type"
msgstr "type de paiement"
#: cotisations/models.py:382
#: cotisations/models.py:378
msgid "address"
msgstr "adresse"
#: cotisations/models.py:383
#: cotisations/models.py:379
msgid "paid"
msgstr "payé"
#: cotisations/models.py:384
#: cotisations/models.py:380
msgid "remark"
msgstr "remarque"
#: cotisations/models.py:389
#: cotisations/models.py:385
msgid "Can view a cost estimate object"
msgstr "Peut voir un objet devis"
#: cotisations/models.py:392
#: cotisations/models.py:388
msgid "period of validity"
msgstr "période de validité"
#: cotisations/models.py:427
#: cotisations/models.py:423
msgid "You don't have the right to delete a cost estimate."
msgstr "Vous n'avez pas le droit de supprimer un devis."
#: cotisations/models.py:433
#: cotisations/models.py:429
msgid "The cost estimate has an invoice and can't be deleted."
msgstr "Le devis a une facture et ne peut pas être supprimé."
#: cotisations/models.py:455 cotisations/models.py:694
#: cotisations/models.py:952
msgid "Connection"
msgstr "Connexion"
#: cotisations/models.py:456 cotisations/models.py:695
#: cotisations/models.py:953
msgid "Membership"
msgstr "Adhésion"
#: cotisations/models.py:457 cotisations/models.py:690
#: cotisations/models.py:696 cotisations/models.py:954
msgid "Both of them"
msgstr "Les deux"
#: cotisations/models.py:466
#: cotisations/models.py:455
msgid "amount"
msgstr "montant"
#: cotisations/models.py:469
#: cotisations/models.py:460
msgid "article"
msgstr "article"
#: cotisations/models.py:472
#: cotisations/models.py:463
msgid "price"
msgstr "prix"
#: cotisations/models.py:475 cotisations/models.py:708
msgid "duration (in months)"
msgstr "durée (en mois)"
#: cotisations/models.py:466 cotisations/models.py:716
msgid "duration of the connection (in months)"
msgstr "durée de la connexion (en mois)"
#: cotisations/models.py:481 cotisations/models.py:714
msgid "duration (in days, will be added to duration in months)"
msgstr "durée (en jours, sera ajoutée à la durée en mois)"
#: cotisations/models.py:471 cotisations/models.py:720
msgid ""
"duration of the connection (in days, will be added to duration in months)"
msgstr "durée de la connexion (en jours, sera ajoutée à la durée en mois)"
#: cotisations/models.py:489 cotisations/models.py:728
#: cotisations/models.py:965
msgid "subscription type"
msgstr "type de cotisation"
#: cotisations/models.py:474 cotisations/models.py:708
msgid "duration of the membership (in months)"
msgstr "durée de l'adhésion (en mois)"
#: cotisations/models.py:494
#: cotisations/models.py:479 cotisations/models.py:712
msgid ""
"duration of the membership (in days, will be added to duration in months)"
msgstr "durée de l'adhésion (en jours, sera ajoutée à la durée en mois)"
#: cotisations/models.py:484
msgid "Can view a purchase object"
msgstr "Peut voir un objet achat"
#: cotisations/models.py:495
#: cotisations/models.py:485
msgid "Can edit all the previous purchases"
msgstr "Peut modifier tous les achats précédents"
#: cotisations/models.py:497 cotisations/models.py:959
#: cotisations/models.py:487 cotisations/models.py:957
msgid "purchase"
msgstr "achat"
#: cotisations/models.py:498
#: cotisations/models.py:488
msgid "purchases"
msgstr "achats"
#: cotisations/models.py:551 cotisations/models.py:748
msgid "Duration must be specified for a subscription."
msgstr "La durée doit être renseignée pour une cotisation."
#: cotisations/models.py:562
#: cotisations/models.py:563
msgid "You don't have the right to edit a purchase."
msgstr "Vous n'avez pas le droit de modifier un achat."
#: cotisations/models.py:568
#: cotisations/models.py:569
msgid "You don't have the right to edit this user's purchases."
msgstr "Vous n'avez pas le droit de modifier les achats de cet utilisateur."
#: cotisations/models.py:577
#: cotisations/models.py:578
msgid ""
"You don't have the right to edit a purchase already controlled or "
"invalidated."
@ -333,15 +319,15 @@ msgstr ""
"Vous n'avez pas le droit de modifier un achat précédemment contrôlé ou "
"invalidé."
#: cotisations/models.py:592
#: cotisations/models.py:593
msgid "You don't have the right to delete a purchase."
msgstr "Vous n'avez pas le droit de supprimer un achat."
#: cotisations/models.py:598
#: cotisations/models.py:599
msgid "You don't have the right to delete this user's purchases."
msgstr "Vous n'avez pas le droit de supprimer les achats de cet utilisateur."
#: cotisations/models.py:605
#: cotisations/models.py:606
msgid ""
"You don't have the right to delete a purchase already controlled or "
"invalidated."
@ -349,134 +335,150 @@ msgstr ""
"Vous n'avez pas le droit de supprimer un achat précédemment contrôlé ou "
"invalidé."
#: cotisations/models.py:621
#: cotisations/models.py:622
msgid "You don't have the right to view someone else's purchase history."
msgstr ""
"Vous n'avez pas le droit de voir l'historique des achats d'un autre "
"utilisateur."
#: cotisations/models.py:689
#: cotisations/models.py:696
msgid "Club"
msgstr "Club"
#: cotisations/models.py:699
#: cotisations/models.py:697
msgid "Both of them"
msgstr "Les deux"
#: cotisations/models.py:700
msgid "designation"
msgstr "désignation"
#: cotisations/models.py:702
#: cotisations/models.py:703
msgid "unit price"
msgstr "prix unitaire"
#: cotisations/models.py:720
#: cotisations/models.py:725
msgid "need membership to be purchased"
msgstr "nécessite une adhésion pour être acheté"
#: cotisations/models.py:732
msgid "type of users concerned"
msgstr "type d'utilisateurs concernés"
#: cotisations/models.py:731 cotisations/models.py:832
#: cotisations/models.py:735 cotisations/models.py:836
msgid "is available for every user"
msgstr "est disponible pour chaque utilisateur"
#: cotisations/models.py:738
#: cotisations/models.py:742
msgid "Can view an article object"
msgstr "Peut voir un objet article"
#: cotisations/models.py:739
#: cotisations/models.py:743
msgid "Can buy every article"
msgstr "Peut acheter chaque article"
#: cotisations/models.py:746
#: cotisations/models.py:750
msgid "Solde is a reserved article name."
msgstr "Solde est un nom d'article réservé."
#: cotisations/models.py:771
#: cotisations/models.py:773
msgid "You can't buy this article."
msgstr "Vous ne pouvez pas acheter cet article."
#: cotisations/models.py:812
#: cotisations/models.py:816
msgid "Can view a bank object"
msgstr "Peut voir un objet banque"
#: cotisations/models.py:813
#: cotisations/models.py:817
msgid "bank"
msgstr "banque"
#: cotisations/models.py:814
#: cotisations/models.py:818
msgid "banks"
msgstr "banques"
#: cotisations/models.py:830
#: cotisations/models.py:834
msgid "method"
msgstr "moyen"
#: cotisations/models.py:837
#: cotisations/models.py:841
msgid "is user balance"
msgstr "est solde utilisateur"
#: cotisations/models.py:838
#: cotisations/models.py:842
msgid "There should be only one balance payment method."
msgstr "Il ne devrait y avoir qu'un moyen de paiement solde."
#: cotisations/models.py:844
#: cotisations/models.py:848
msgid "Can view a payment method object"
msgstr "Peut voir un objet moyen de paiement"
#: cotisations/models.py:845
#: cotisations/models.py:849
msgid "Can use every payment method"
msgstr "Peut utiliser chaque moyen de paiement"
#: cotisations/models.py:847
#: cotisations/models.py:851
msgid "payment method"
msgstr "moyen de paiement"
#: cotisations/models.py:848
#: cotisations/models.py:852
msgid "payment methods"
msgstr "moyens de paiement"
#: cotisations/models.py:887 cotisations/payment_methods/comnpay/views.py:62
#: cotisations/models.py:891 cotisations/payment_methods/comnpay/views.py:62
#, python-format
msgid "The subscription of %(member_name)s was extended to %(end_date)s."
msgstr "La cotisation de %(member_name)s a été étendue au %(end_date)s."
#: cotisations/models.py:897
#: cotisations/models.py:901
msgid "The invoice was created."
msgstr "La facture a été créée."
#: cotisations/models.py:917
#: cotisations/models.py:921
msgid "You can't use this payment method."
msgstr "Vous ne pouvez pas utiliser ce moyen de paiement."
#: cotisations/models.py:936
#: cotisations/models.py:940
msgid "No custom payment methods."
msgstr "Pas de moyens de paiement personnalisés."
#: cotisations/models.py:967
msgid "start date"
msgstr "date de début"
#: cotisations/models.py:959
msgid "start date for the connection"
msgstr "date de début pour la connexion"
#: cotisations/models.py:968
msgid "end date"
msgstr "date de fin"
#: cotisations/models.py:960
msgid "end date for the connection"
msgstr "date de fin pour la connexion"
#: cotisations/models.py:972
#: cotisations/models.py:961
msgid "start date for the membership"
msgstr "date de début pour l'adhésion"
#: cotisations/models.py:962
msgid "end date for the membership"
msgstr "date de fin pour l'adhésion"
#: cotisations/models.py:966
msgid "Can view a subscription object"
msgstr "Peut voir un objet cotisation"
#: cotisations/models.py:973
#: cotisations/models.py:967
msgid "Can edit the previous subscriptions"
msgstr "Peut modifier les cotisations précédentes"
#: cotisations/models.py:975
#: cotisations/models.py:969
msgid "subscription"
msgstr "cotisation"
#: cotisations/models.py:976
#: cotisations/models.py:970
msgid "subscriptions"
msgstr "cotisations"
#: cotisations/models.py:982
#: cotisations/models.py:976
msgid "You don't have the right to edit a subscription."
msgstr "Vous n'avez pas le droit de modifier une cotisation."
#: cotisations/models.py:991
#: cotisations/models.py:985
msgid ""
"You don't have the right to edit a subscription already controlled or "
"invalidated."
@ -484,11 +486,11 @@ msgstr ""
"Vous n'avez pas le droit de modifier une cotisation précédemment contrôlée "
"ou invalidée."
#: cotisations/models.py:1003
#: cotisations/models.py:997
msgid "You don't have the right to delete a subscription."
msgstr "Vous n'avez pas le droit de supprimer une cotisation."
#: cotisations/models.py:1010
#: cotisations/models.py:1004
msgid ""
"You don't have the right to delete a subscription already controlled or "
"invalidated."
@ -496,7 +498,7 @@ msgstr ""
"Vous n'avez pas le droit de supprimer une cotisation précédemment contrôlée "
"ou invalidée."
#: cotisations/models.py:1026
#: cotisations/models.py:1020
msgid "You don't have the right to view someone else's subscription history."
msgstr ""
"Vous n'avez pas le droit de voir l'historique des cotisations d'un autre "
@ -646,22 +648,26 @@ msgid "Price"
msgstr "Prix"
#: cotisations/templates/cotisations/aff_article.html:35
msgid "Subscription type"
msgstr "Type de cotisation"
msgid "Duration membership (in months)"
msgstr "Durée adhésion (en mois)"
#: cotisations/templates/cotisations/aff_article.html:36
msgid "Duration (in months)"
msgstr "Durée (en mois)"
msgid "Duration membership (in days)"
msgstr "Durée adhésion (en jours)"
#: cotisations/templates/cotisations/aff_article.html:37
msgid "Duration (in days)"
msgstr "Durée (en jours)"
msgid "Duration connection (in months)"
msgstr "Durée connexion (en mois)"
#: cotisations/templates/cotisations/aff_article.html:38
msgid "Duration connection (in days)"
msgstr "Durée connexion (en jours)"
#: cotisations/templates/cotisations/aff_article.html:39
msgid "Concerned users"
msgstr "Utilisateurs concernés"
#: cotisations/templates/cotisations/aff_article.html:39
#: cotisations/templates/cotisations/aff_article.html:40
#: cotisations/templates/cotisations/aff_paiement.html:34
msgid "Available for everyone"
msgstr "Disponible pour tous"
@ -710,7 +716,7 @@ msgid "Invoice created"
msgstr "Facture créée"
#: cotisations/templates/cotisations/aff_cost_estimate.html:91
#: cotisations/templates/cotisations/aff_cotisations.html:81
#: cotisations/templates/cotisations/aff_cotisations.html:91
#: cotisations/templates/cotisations/aff_custom_invoice.html:79
msgid "PDF"
msgstr "PDF"
@ -725,15 +731,15 @@ msgstr "Utilisateur"
msgid "Invoice ID"
msgstr "ID facture"
#: cotisations/templates/cotisations/aff_cotisations.html:71
#: cotisations/templates/cotisations/aff_cotisations.html:81
msgid "Controlled invoice"
msgstr "Facture contrôlée"
#: cotisations/templates/cotisations/aff_cotisations.html:84
#: cotisations/templates/cotisations/aff_cotisations.html:94
msgid "Invalidated invoice"
msgstr "Facture invalidée"
#: cotisations/templates/cotisations/aff_cotisations.html:88
#: cotisations/templates/cotisations/aff_cotisations.html:98
msgid "Voucher"
msgstr "Reçu"
@ -749,6 +755,23 @@ msgstr "Type de paiement"
msgid "Custom payment method"
msgstr "Moyen de paiement personnalisé"
#: cotisations/templates/cotisations/aff_profil.html:35
#: cotisations/templates/cotisations/index.html:32
msgid "Subscriptions"
msgstr "Cotisations"
#: cotisations/templates/cotisations/aff_profil.html:43
msgid "Add a subscription"
msgstr "Ajouter une cotisation"
#: cotisations/templates/cotisations/aff_profil.html:48
msgid "Edit the balance"
msgstr "Modifier le solde utilisateur"
#: cotisations/templates/cotisations/aff_profil.html:57
msgid "No invoice"
msgstr "Pas de facture"
#: cotisations/templates/cotisations/control.html:30
msgid "Invoice control"
msgstr "Contrôle des factures"
@ -784,7 +807,7 @@ msgstr "Contrôlé"
#: cotisations/templates/cotisations/control.html:107
#: cotisations/templates/cotisations/delete.html:38
#: cotisations/templates/cotisations/edit_facture.html:64
#: cotisations/views.py:170 cotisations/views.py:222 cotisations/views.py:276
#: cotisations/views.py:172 cotisations/views.py:224 cotisations/views.py:280
msgid "Confirm"
msgstr "Confirmer"
@ -813,7 +836,6 @@ msgstr "Modifier la facture"
#: cotisations/templates/cotisations/edit_facture.html:45
#: cotisations/templates/cotisations/facture.html:59
#: cotisations/templates/cotisations/index_article.html:30
#: cotisations/templates/cotisations/sidebar.html:55
msgid "Articles"
msgstr "Articles"
@ -840,14 +862,9 @@ msgid "Total price: <span id=\"total_price\">0,00</span> €"
msgstr "Prix total : <span id=\"total_price\">0,00</span> €"
#: cotisations/templates/cotisations/index.html:29
#: cotisations/templates/cotisations/sidebar.html:40
msgid "Invoices"
msgstr "Factures"
#: cotisations/templates/cotisations/index.html:32
msgid "Subscriptions"
msgstr "Cotisations"
#: cotisations/templates/cotisations/index_article.html:33
msgid "List of articles"
msgstr "Liste des articles"
@ -861,7 +878,6 @@ msgid "Delete one or several articles"
msgstr "Supprimer un ou plusieurs articles"
#: cotisations/templates/cotisations/index_banque.html:30
#: cotisations/templates/cotisations/sidebar.html:60
msgid "Banks"
msgstr "Banques"
@ -878,7 +894,6 @@ msgid "Delete one or several banks"
msgstr "Supprimer une ou plusieurs banques"
#: cotisations/templates/cotisations/index_cost_estimate.html:28
#: cotisations/templates/cotisations/sidebar.html:50
msgid "Cost estimates"
msgstr "Devis"
@ -887,7 +902,6 @@ msgid "List of cost estimates"
msgstr "Liste des devis"
#: cotisations/templates/cotisations/index_custom_invoice.html:28
#: cotisations/templates/cotisations/sidebar.html:45
msgid "Custom invoices"
msgstr "Factures personnalisées"
@ -896,7 +910,6 @@ msgid "List of custom invoices"
msgstr "Liste des factures personnalisées"
#: cotisations/templates/cotisations/index_paiement.html:30
#: cotisations/templates/cotisations/sidebar.html:65
msgid "Payment methods"
msgstr "Moyens de paiement"
@ -921,132 +934,124 @@ msgstr "Rechargement de solde"
msgid "Pay %(amount)s €"
msgstr "Payer %(amount)s €"
#: cotisations/templates/cotisations/payment.html:42 cotisations/views.py:1026
#: cotisations/templates/cotisations/payment.html:42 cotisations/views.py:1030
msgid "Pay"
msgstr "Payer"
#: cotisations/templates/cotisations/sidebar.html:32
msgid "Create an invoice"
msgstr "Créer une facture"
#: cotisations/templates/cotisations/sidebar.html:35
msgid "Control the invoices"
msgstr "Contrôler les factures"
#: cotisations/views.py:157
#: cotisations/views.py:159
msgid "You need to choose at least one article."
msgstr "Vous devez choisir au moins un article."
#: cotisations/views.py:171
#: cotisations/views.py:173
msgid "New invoice"
msgstr "Nouvelle facture"
#: cotisations/views.py:216
#: cotisations/views.py:218
msgid "The cost estimate was created."
msgstr "Le devis a été créé."
#: cotisations/views.py:226
#: cotisations/views.py:228
msgid "New cost estimate"
msgstr "Nouveau devis"
#: cotisations/views.py:270
#: cotisations/views.py:274
msgid "The custom invoice was created."
msgstr "La facture personnalisée a été créée."
#: cotisations/views.py:280
#: cotisations/views.py:284
msgid "New custom invoice"
msgstr "Nouvelle facture personnalisée"
#: cotisations/views.py:355 cotisations/views.py:436
#: cotisations/views.py:359 cotisations/views.py:440
msgid "The invoice was edited."
msgstr "La facture a été modifiée."
#: cotisations/views.py:373 cotisations/views.py:568
#: cotisations/views.py:377 cotisations/views.py:572
msgid "The invoice was deleted."
msgstr "La facture a été supprimée."
#: cotisations/views.py:396
#: cotisations/views.py:400
msgid "The cost estimate was edited."
msgstr "Le devis a été modifié."
#: cotisations/views.py:403
#: cotisations/views.py:407
msgid "Edit cost estimate"
msgstr "Modifier le devis"
#: cotisations/views.py:417
#: cotisations/views.py:421
msgid "An invoice was successfully created from your cost estimate."
msgstr "Une facture a bien été créée à partir de votre devis."
#: cotisations/views.py:443
#: cotisations/views.py:447
msgid "Edit custom invoice"
msgstr "Modifier la facture personnalisée"
#: cotisations/views.py:505
#: cotisations/views.py:509
msgid "The cost estimate was deleted."
msgstr "Le devis a été supprimé."
#: cotisations/views.py:508
#: cotisations/views.py:512
msgid "cost estimate"
msgstr "devis"
#: cotisations/views.py:592
#: cotisations/views.py:596
msgid "The article was created."
msgstr "L'article a été créé."
#: cotisations/views.py:597 cotisations/views.py:671 cotisations/views.py:765
#: cotisations/views.py:601 cotisations/views.py:675 cotisations/views.py:769
msgid "Add"
msgstr "Ajouter"
#: cotisations/views.py:598
#: cotisations/views.py:602
msgid "New article"
msgstr "Nouvel article"
#: cotisations/views.py:615
#: cotisations/views.py:619
msgid "The article was edited."
msgstr "L'article a été modifié."
#: cotisations/views.py:620 cotisations/views.py:703 cotisations/views.py:789
#: cotisations/views.py:624 cotisations/views.py:707 cotisations/views.py:793
msgid "Edit"
msgstr "Modifier"
#: cotisations/views.py:621
#: cotisations/views.py:625
msgid "Edit article"
msgstr "Modifier l'article"
#: cotisations/views.py:638
#: cotisations/views.py:642
msgid "The articles were deleted."
msgstr "Les articles ont été supprimés."
#: cotisations/views.py:643 cotisations/views.py:742 cotisations/views.py:827
#: cotisations/views.py:647 cotisations/views.py:746 cotisations/views.py:831
msgid "Delete"
msgstr "Supprimer"
#: cotisations/views.py:644
#: cotisations/views.py:648
msgid "Delete article"
msgstr "Supprimer l'article"
#: cotisations/views.py:665
#: cotisations/views.py:669
msgid "The payment method was created."
msgstr "Le moyen de paiment a été créé."
#: cotisations/views.py:672
#: cotisations/views.py:676
msgid "New payment method"
msgstr "Nouveau moyen de paiement"
#: cotisations/views.py:697
#: cotisations/views.py:701
msgid "The payment method was edited."
msgstr "Le moyen de paiment a été modifié."
#: cotisations/views.py:704
#: cotisations/views.py:708
msgid "Edit payment method"
msgstr "Modifier le moyen de paiement"
#: cotisations/views.py:726
#: cotisations/views.py:730
#, python-format
msgid "The payment method %(method_name)s was deleted."
msgstr "Le moyen de paiement %(method_name)s a été supprimé."
#: cotisations/views.py:733
#: cotisations/views.py:737
#, python-format
msgid ""
"The payment method %(method_name)s can't be deleted because there are "
@ -1055,32 +1060,32 @@ msgstr ""
"Le moyen de paiement %(method_name)s ne peut pas être supprimé car il y a "
"des factures qui l'utilisent."
#: cotisations/views.py:743
#: cotisations/views.py:747
msgid "Delete payment method"
msgstr "Supprimer le moyen de paiement"
#: cotisations/views.py:760
#: cotisations/views.py:764
msgid "The bank was created."
msgstr "La banque a été créée."
#: cotisations/views.py:766
#: cotisations/views.py:770
msgid "New bank"
msgstr "Nouvelle banque"
#: cotisations/views.py:784
#: cotisations/views.py:788
msgid "The bank was edited."
msgstr "La banque a été modifiée."
#: cotisations/views.py:790
#: cotisations/views.py:794
msgid "Edit bank"
msgstr "Modifier la banque"
#: cotisations/views.py:812
#: cotisations/views.py:816
#, python-format
msgid "The bank %(bank_name)s was deleted."
msgstr "La banque %(bank_name)s a été supprimée."
#: cotisations/views.py:818
#: cotisations/views.py:822
#, python-format
msgid ""
"The bank %(bank_name)s can't be deleted because there are invoices using it."
@ -1088,22 +1093,22 @@ msgstr ""
"La banque %(bank_name)s ne peut pas être supprimée car il y a des factures "
"qui l'utilisent."
#: cotisations/views.py:828
#: cotisations/views.py:832
msgid "Delete bank"
msgstr "Supprimer la banque"
#: cotisations/views.py:862
#: cotisations/views.py:866
msgid "Your changes have been properly taken into account."
msgstr "Vos modifications ont correctement été prises en compte."
#: cotisations/views.py:994
#: cotisations/views.py:998
msgid "You are not allowed to credit your balance."
msgstr "Vous n'êtes pas autorisé à créditer votre solde."
#: cotisations/views.py:1025
#: cotisations/views.py:1029
msgid "Refill your balance"
msgstr "Recharger votre solde"
#: cotisations/views.py:1044
#: cotisations/views.py:1048
msgid "Could not find a voucher for that invoice."
msgstr "Impossible de trouver un reçu pour cette facture."

View file

@ -27,43 +27,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load i18n %}
{% block sidebar %}
{% can_create CustomInvoice %}
<a class="list-group-item list-group-item-success" href="{% url 'cotisations:new-custom-invoice' %}">
<i class="fa fa-plus"></i> {% trans "Create an invoice" %}
</a>
<a class="list-group-item list-group-item-warning" href="{% url 'cotisations:control' %}">
<i class="fa fa-eye"></i> {% trans "Control the invoices" %}
</a>
{% acl_end %}
{% can_view_all Facture %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index' %}">
<i class="fa fa-list-ul"></i> {% trans "Invoices" %}
</a>
{% acl_end %}
{% can_view_all CustomInvoice %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index-custom-invoice' %}">
<i class="fa fa-list-ul"></i> {% trans "Custom invoices" %}
</a>
{% acl_end %}
{% can_view_all CostEstimate %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index-cost-estimate' %}">
<i class="fa fa-list-ul"></i> {% trans "Cost estimates" %}
</a>
{% acl_end %}
{% can_view_all Article %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index-article' %}">
<i class="fa fa-list-ul"></i> {% trans "Articles" %}
</a>
{% acl_end %}
{% can_view_all Banque %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index-banque' %}">
<i class="fa fa-list-ul"></i> {% trans "Banks" %}
</a>
{% acl_end %}
{% can_view_all Paiement %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index-paiement' %}">
<i class="fa fa-list-ul"></i> {% trans "Payment methods" %}
</a>
{% acl_end %}
{% endblock %}

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2018-06-23 16:01+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -34,7 +34,7 @@ msgstr ""
msgid "You don't have the right to view this application."
msgstr "Vous n'avez pas le droit de voir cette application."
#: logs/forms.py:40 logs/templates/logs/sidebar.html:53
#: logs/forms.py:40
msgid "Users"
msgstr "Utilisateurs"
@ -54,7 +54,7 @@ msgstr "Accès gracieux"
msgid "Bans"
msgstr "Bannissements"
#: logs/forms.py:45 logs/views.py:430
#: logs/forms.py:45 logs/views.py:437
msgid "Topology"
msgstr "Topologie"
@ -70,49 +70,49 @@ msgstr "IPv4"
msgid "MAC address"
msgstr "Adresse MAC"
#: logs/forms.py:101
#: logs/forms.py:118
msgid "Performed by"
msgstr "Effectué(e) par"
#: logs/forms.py:106
#: logs/forms.py:123
msgid "Action type"
msgstr "Type d'action"
#: logs/forms.py:112 logs/forms.py:135
#: logs/forms.py:129 logs/forms.py:152
#: logs/templates/logs/machine_history.html:37
msgid "Start date"
msgstr "Date de début"
#: logs/forms.py:113 logs/forms.py:136
#: logs/forms.py:130 logs/forms.py:153
#: logs/templates/logs/machine_history.html:38
msgid "End date"
msgstr "Date de fin"
#: logs/forms.py:128 logs/templates/logs/search_machine_history.html:38
#: logs/forms.py:145 logs/templates/logs/search_machine_history.html:38
#: logs/templates/logs/search_stats_logs.html:36
msgid "Search"
msgstr "Rechercher"
#: logs/forms.py:132
#: logs/forms.py:149
msgid "Search type"
msgstr "Type de recherche"
#: logs/models.py:310 logs/models.py:552 logs/models.py:585 logs/models.py:798
#: logs/models.py:359 logs/models.py:666 logs/models.py:699 logs/models.py:938
msgid "None"
msgstr "Aucun(e)"
#: logs/models.py:562 logs/models.py:581 logs/models.py:595 logs/models.py:749
#: logs/models.py:785 logs/models.py:790 logs/models.py:795 logs/models.py:805
#: logs/views.py:605
#: logs/models.py:676 logs/models.py:695 logs/models.py:709 logs/models.py:876
#: logs/models.py:925 logs/models.py:930 logs/models.py:935 logs/models.py:945
#: logs/views.py:611
msgid "Deleted"
msgstr "Supprimé(e)"
#: logs/models.py:569 logs/models.py:574
#: logs/models.py:683 logs/models.py:688
#: logs/templates/logs/machine_history.html:55
msgid "Unknown"
msgstr "Inconnu(e)"
#: logs/models.py:793
#: logs/models.py:933
msgid "No name"
msgstr "Sans nom"
@ -249,7 +249,7 @@ msgid "Statistics"
msgstr "Statistiques"
#: logs/templates/logs/index.html:32 logs/templates/logs/stats_logs.html:32
#: logs/views.py:445
#: logs/views.py:452
msgid "Actions performed"
msgstr "Actions effectuées"
@ -279,30 +279,6 @@ msgstr "Rechercher l'historique des machines"
msgid "Search events"
msgstr "Recherche les évènements"
#: logs/templates/logs/sidebar.html:33
msgid "Summary"
msgstr "Résumé"
#: logs/templates/logs/sidebar.html:37
msgid "Events"
msgstr "Évènements"
#: logs/templates/logs/sidebar.html:41
msgid "General"
msgstr "Général"
#: logs/templates/logs/sidebar.html:45
msgid "Database"
msgstr "Base de données"
#: logs/templates/logs/sidebar.html:49
msgid "Wiring actions"
msgstr "Actions de câblage"
#: logs/templates/logs/sidebar.html:57
msgid "Machine history"
msgstr "Historique des machines"
#: logs/templates/logs/stats_general.html:32
msgid "General statistics"
msgstr "Statistiques générales"
@ -315,138 +291,156 @@ msgstr "Statistiques sur la base de données"
msgid "Statistics about users"
msgstr "Statistiques sur les utilisateurs"
#: logs/views.py:192
#: logs/views.py:198
msgid "Nonexistent revision."
msgstr "Révision inexistante."
#: logs/views.py:195
#: logs/views.py:201
msgid "The action was deleted."
msgstr "L'action a été supprimée."
#: logs/views.py:236
#: logs/views.py:243
msgid "Category"
msgstr "Catégorie"
#: logs/views.py:237
#: logs/views.py:244
msgid "Number of users (members and clubs)"
msgstr "Nombre d'utilisateurs (adhérents et clubs)"
#: logs/views.py:238
#: logs/views.py:245
msgid "Number of members"
msgstr "Nombre d'adhérents"
#: logs/views.py:239
#: logs/views.py:246
msgid "Number of clubs"
msgstr "Nombre de clubs"
#: logs/views.py:243
#: logs/views.py:250
msgid "Activated users"
msgstr "Utilisateurs activés"
#: logs/views.py:249
#: logs/views.py:256
msgid "Disabled users"
msgstr "Utilisateurs désactivés"
#: logs/views.py:255
#: logs/views.py:262
msgid "Archived users"
msgstr "Utilisateurs archivés"
#: logs/views.py:261
#: logs/views.py:268
msgid "Fully archived users"
msgstr "Utilisateurs complètement archivés"
#: logs/views.py:271
#: logs/views.py:278
msgid "Not yet active users"
msgstr "Utilisateurs pas encore actifs"
#: logs/views.py:281
#: logs/views.py:288
msgid "Contributing members"
msgstr "Adhérents cotisants"
#: logs/views.py:287
#: logs/views.py:294
msgid "Users benefiting from a connection"
msgstr "Utilisateurs bénéficiant d'une connexion"
#: logs/views.py:293
#: logs/views.py:300
msgid "Banned users"
msgstr "Utilisateurs bannis"
#: logs/views.py:299
#: logs/views.py:306
msgid "Users benefiting from a free connection"
msgstr "Utilisateurs bénéficiant d'une connexion gratuite"
#: logs/views.py:305
#: logs/views.py:312
msgid "Users with a confirmed email"
msgstr "Utilisateurs ayant un mail confirmé"
#: logs/views.py:313
#: logs/views.py:320
msgid "Users with an unconfirmed email"
msgstr "Utilisateurs ayant un mail non confirmé"
#: logs/views.py:325
#: logs/views.py:332
msgid "Users pending email confirmation"
msgstr "Utilisateurs en attente de confirmation du mail"
#: logs/views.py:333
#: logs/views.py:340
msgid "Active interfaces (with access to the network)"
msgstr "Interfaces actives (ayant accès au réseau)"
#: logs/views.py:347
#: logs/views.py:354
msgid "Active interfaces assigned IPv4"
msgstr "Interfaces actives assignées IPv4"
#: logs/views.py:364
#: logs/views.py:371
msgid "IP range"
msgstr "Plage d'IP"
#: logs/views.py:365
#: logs/views.py:372
msgid "VLAN"
msgstr "VLAN"
#: logs/views.py:366
#: logs/views.py:373
msgid "Total number of IP addresses"
msgstr "Nombre total d'adresses IP"
#: logs/views.py:367
#: logs/views.py:374
msgid "Number of assigned IP addresses"
msgstr "Nombre d'adresses IP assignées"
#: logs/views.py:368
#: logs/views.py:375
msgid "Number of IP address assigned to an activated machine"
msgstr "Nombre d'adresses IP assignées à une machine activée"
#: logs/views.py:369
#: logs/views.py:376
msgid "Number of unassigned IP addresses"
msgstr "Nombre d'adresses IP non assignées"
#: logs/views.py:384
#: logs/views.py:391
msgid "Users (members and clubs)"
msgstr "Utilisateurs (adhérents et clubs)"
#: logs/views.py:446
#: logs/views.py:453
msgid "Number of actions"
msgstr "Nombre d'actions"
#: logs/views.py:473
#: logs/views.py:479
msgid "rights"
msgstr "droits"
#: logs/views.py:504
#: logs/views.py:508
msgid "actions"
msgstr "actions"
#: logs/views.py:549
#: logs/views.py:555
msgid "You don't have the right to access this menu."
msgstr "Vous n'avez pas le droit d'accéder à ce menu."
#: logs/views.py:584
#: logs/views.py:590
msgid "No model found."
msgstr "Aucun modèle trouvé."
#: logs/views.py:595
#: logs/views.py:601
msgid "Nonexistent entry."
msgstr "Entrée inexistante."
#~ msgid "Summary"
#~ msgstr "Résumé"
#~ msgid "Events"
#~ msgstr "Évènements"
#~ msgid "General"
#~ msgstr "Général"
#~ msgid "Database"
#~ msgstr "Base de données"
#~ msgid "Wiring actions"
#~ msgstr "Actions de câblage"
#~ msgid "Machine history"
#~ msgstr "Historique des machines"
#~ msgid "History of %(title)s"
#~ msgstr "Historique de %(title)s"

View file

@ -27,35 +27,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load i18n %}
{% block sidebar %}
{% can_view_app logs %}
<a class="list-group-item list-group-item-info" href="{% url 'logs:index' %}">
<i class="fa fa-clipboard"></i>
{% trans "Summary" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'logs:stats-logs' %}">
<i class="fa fa-calendar"></i>
{% trans "Events" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'logs:stats-general' %}">
<i class="fa fa-area-chart"></i>
{% trans "General" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'logs:stats-models' %}">
<i class="fa fa-database"></i>
{% trans "Database" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'logs:stats-actions' %}">
<i class="fa fa-plug"></i>
{% trans "Wiring actions" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'logs:stats-users' %}">
<i class="fa fa-users"></i>
{% trans "Users" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'logs:stats-search-machine' %}">
<i class="fa fa-desktop"></i>
{% trans "Machine history" %}
</a>
{% acl_end %}
{% endblock %}

File diff suppressed because it is too large Load diff

View file

@ -27,59 +27,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load i18n %}
{% block sidebar %}
{% can_view_all Machine %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index' %}">
<i class="fa fa-list-ul"></i>
{% trans "Machines" %}
</a>
{% acl_end %}
{% can_view_all MachineType %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-machinetype' %}">
<i class="fa fa-list-ul"></i>
{% trans "Machine types" %}
</a>
{% acl_end %}
{% can_view_all Extension %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-extension' %}">
<i class="fa fa-list-ul"></i>
{% trans "Extensions and zones" %}
</a>
{% acl_end %}
{% can_view_all IpType %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-iptype' %}">
<i class="fa fa-list-ul"></i>
{% trans "IP ranges" %}
</a>
{% acl_end %}
{% can_view_all Vlan %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-vlan' %}">
<i class="fa fa-list-ul"></i>
{% trans "VLANs" %}
</a>
{% acl_end %}
{% can_view_all Nas %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-nas' %}">
<i class="fa fa-list-ul"></i>
{% trans "NAS devices" %}
</a>
{% acl_end %}
{% can_view_all machines.Service %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-service' %}">
<i class="fa fa-list-ul"></i>
{% trans "Services (DHCP, DNS, ...)" %}
</a>
{% acl_end %}
{% can_view_all Role %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-role' %}">
<i class="fa fa-list-ul"></i>
{% trans "Server roles" %}
</a>
{% acl_end %}
{% can_view_all OuverturePortList %}
<a class="list-group-item list-group-item-info" href="{% url 'machines:index-portlist' %}">
<i class="fa fa-list-ul"></i>
{% trans "Ports openings" %}
</a>
{% acl_end %}
{% endblock %}

View file

@ -21,79 +21,67 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2019-11-16 00:22+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Last-Translator: Yoann Piétri <me@nanoy.fr>\n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: multi_op/forms.py:43
#: multi_op/forms.py:44
msgid "Dormitory"
msgstr "Résidence"
#: multi_op/preferences/models.py:37
#: multi_op/preferences/models.py:41
msgid "enabled dorm"
msgstr "résidence activée"
#: multi_op/preferences/models.py:41
#: multi_op/preferences/models.py:45
msgid "dormitories preferences"
msgstr "préférences de résidences"
#: multi_op/templates/multi_op/aff_room_state.html:36
msgid "Room"
msgstr "Chambre"
#: multi_op/templates/multi_op/aff_room_state.html:37
msgid "Building"
msgstr "Bâtiment"
#: multi_op/templates/multi_op/aff_room_state.html:40
msgid "Connnected to"
msgstr "Connectée à"
#: multi_op/templates/multi_op/aff_room_state.html:41
#: multi_op/templates/multi_op/aff_room_state.html:54
msgid "User"
msgstr "Utilisateur"
#: multi_op/templates/multi_op/aff_room_state.html:42
msgid "Details"
msgstr "Détails"
#: multi_op/templates/multi_op/aff_room_state.html:55
msgid "Connected to"
msgstr "Connectée à"
#: multi_op/templates/multi_op/aff_room_state.html:43
#: multi_op/templates/multi_op/aff_room_state.html:56
msgid "End of subscription on"
msgstr "Fin de cotisation le"
#: multi_op/templates/multi_op/aff_room_state.html:44
#: multi_op/templates/multi_op/aff_room_state.html:57
msgid "Internet access"
msgstr "Accès Internet"
#: multi_op/templates/multi_op/aff_room_state.html:45
msgid "Action"
msgstr "Action"
#: multi_op/templates/multi_op/aff_room_state.html:52
msgid "Other operator"
msgstr "Autre opérateur"
#: multi_op/templates/multi_op/aff_room_state.html:53
#: multi_op/templates/multi_op/aff_room_state.html:65
msgid "None"
msgstr "Aucun"
#: multi_op/templates/multi_op/aff_room_state.html:55
#: multi_op/templates/multi_op/aff_room_state.html:72
msgid "Other operator"
msgstr "Autre opérateur"
#: multi_op/templates/multi_op/aff_room_state.html:84
msgid "Non member"
msgstr "Non adhérent"
#: multi_op/templates/multi_op/aff_room_state.html:58
#: multi_op/templates/multi_op/aff_room_state.html:90
msgid "Active"
msgstr "Actif"
#: multi_op/templates/multi_op/aff_room_state.html:60
#: multi_op/templates/multi_op/aff_room_state.html:92
msgid "Disabled"
msgstr "Désactivé"
#: multi_op/templates/multi_op/aff_room_state.html:101
msgid "Details: "
msgstr "Détails :"
#: multi_op/templates/multi_op/index_room_state.html:30
msgid "Multiple operators"
msgstr "Opérateurs multiples"
@ -106,23 +94,35 @@ msgstr "Connexions de chambre"
msgid "Select dormitory"
msgstr "Sélectionnez la résidence"
#: multi_op/templates/multi_op/navbar.html:2
msgid "Manage the operators"
msgstr "Gérer les opérateurs"
#: multi_op/templates/multi_op/navbar.html:3
msgid "Multi op"
msgstr "Opérateurs multiples"
#: multi_op/templates/multi_op/sidebar.html:31
#: multi_op/templates/multi_op/navbar.html:7
msgid "Room connections state"
msgstr "État des connexions de chambre"
#: multi_op/templates/multi_op/sidebar.html:35
#: multi_op/templates/multi_op/navbar.html:10
msgid "Sockets to connect"
msgstr "Prises à connecter"
#: multi_op/templates/multi_op/sidebar.html:39
#: multi_op/templates/multi_op/navbar.html:13
msgid "Sockets to disconnect"
msgstr "Prises à déconnecter"
#: multi_op/views.py:169
#: multi_op/templates/multi_op/preferences.html:7
msgid "Multi Op"
msgstr "Opérateurs Multiples"
#: multi_op/templates/multi_op/preferences.html:14
msgid "Edit"
msgstr "Modifier"
#: multi_op/templates/multi_op/preferences.html:21
msgid "Enabled Dorm"
msgstr "Résidence Activée"
#: multi_op/views.py:194
#, python-format
msgid "The room %s was disconnected."
msgstr "La chambre %s a été déconnectée."

View file

@ -1,2 +1,15 @@
{% load i18n %}
<li><a href="{% url 'multi_op:aff-state-global' %}"><i class="fa fa-random"></i> {% trans "Manage the operators" %}</a></li>
<li><a class="dropdown-item" href="#"><i class="fa fa-random"></i>
{% trans "Multi op" %} &raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'multi_op:aff-state-global' %}"><i
class="fa fa-random"></i>
{% trans "Room connections state" %}</a></li>
<li><a class="dropdown-item" href="{% url 'multi_op:aff-pending-connection' %}"><i
class="fa fa-compress"></i>
{% trans "Sockets to connect" %}</a></li>
<li><a class="dropdown-item" href="{% url 'multi_op:aff-pending-disconnection' %}"><i
class="fa fa-expand"></i>
{% trans "Sockets to disconnect" %}</a></li>
</ul>
</li>

View file

@ -26,18 +26,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load i18n %}
{% block sidebar %}
<a class="list-group-item list-group-item-info" href="{% url 'multi_op:aff-state-global' %}">
<i class="fa fa-random"></i>
{% trans "Room connections state" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'multi_op:aff-pending-connection' %}">
<i class="fa fa-compress"></i>
{% trans "Sockets to connect" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'multi_op:aff-pending-disconnection' %}">
<i class="fa fa-expand"></i>
{% trans "Sockets to disconnect" %}
</a>
{% endblock %}

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}{% trans "Preferences" %}{% endblock %}
{% block content %}
<h2>{% trans "Preferences" %}</h2>
<div id="accordion">
<div class="panel panel-default" id="general">

View file

@ -21,9 +21,9 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Last-Translator: Yoann Piétri <me@nanoy.fr>\n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
@ -44,32 +44,32 @@ msgstr "Vous devez être membre de l'un de ces groupes : %s."
msgid "No group has the %s permission(s)!"
msgstr "Aucun groupe ne possède la ou les permissions %s !"
#: re2o/acl.py:166
#: re2o/acl.py:194
msgid "Nonexistent entry."
msgstr "Entrée inexistante."
#: re2o/acl.py:196 re2o/acl.py:267
#: re2o/acl.py:250 re2o/acl.py:322
msgid "You don't have the right to access this menu."
msgstr "Vous n'avez pas le droit d'accéder à ce menu."
#: re2o/acl.py:317
#: re2o/acl.py:372
msgid "You don't have the right to edit the history."
msgstr "Vous n'avez pas le droit de modifier l'historique."
#: re2o/base.py:76
#: re2o/base.py:74
msgid "This domain is already taken."
msgstr "Ce domaine est déjà pris."
#: re2o/base.py:78
#: re2o/base.py:76
msgid "SMTP unreachable."
msgstr "SMTP injoignable."
#: re2o/base.py:99
#: re2o/base.py:97
#, python-brace-format
msgid "Format: {main} {more}"
msgstr "Format : {main} {more}"
#: re2o/base.py:101
#: re2o/base.py:99
#, python-brace-format
msgid "Format: {main}"
msgstr "Format : {main}"
@ -79,40 +79,40 @@ msgstr "Format : {main}"
msgid "Failed to send email: %(error)s."
msgstr "Échec de l'envoi du mail : %(error)s."
#: re2o/mixins.py:110
#: re2o/mixins.py:121
#, python-format
msgid "You don't have the right to create a %s object."
msgstr "Vous n'avez pas le droit de créer un objet %s."
#: re2o/mixins.py:126
#: re2o/mixins.py:142
#, python-format
msgid "You don't have the right to edit a %s object."
msgstr "Vous n'avez pas le droit de modifier un objet %s."
#: re2o/mixins.py:142
#: re2o/mixins.py:163
#, python-format
msgid "You don't have the right to delete a %s object."
msgstr "Vous n'avez pas le droit de supprimer un objet %s."
#: re2o/mixins.py:158
#: re2o/mixins.py:184
#, python-format
msgid "You don't have the right to view every %s object."
msgstr "Vous n'avez pas le droit de voir tous les objets %s."
#: re2o/mixins.py:174
#: re2o/mixins.py:205
#, python-format
msgid "You don't have the right to view a %s object."
msgstr "Vous n'avez pas le droit de voir un objet %s."
#: re2o/settings.py:150
#: re2o/settings.py:154
msgid "English"
msgstr "Anglais"
#: re2o/settings.py:150
#: re2o/settings.py:154
msgid "French"
msgstr "Français"
#: re2o/templates/re2o/about.html:29 re2o/templates/re2o/about.html:54
#: re2o/templates/re2o/about.html:29 re2o/templates/re2o/about.html:56
msgid "About Re2o"
msgstr "À propos de Re2o"
@ -140,15 +140,15 @@ msgstr "Gestionnaire de publication"
msgid "President of "
msgstr "Président de "
#: re2o/templates/re2o/about.html:46
#: re2o/templates/re2o/about.html:47
msgid "General Terms of Use"
msgstr "Conditions Générales d'Utilisation"
#: re2o/templates/re2o/about.html:50
#: re2o/templates/re2o/about.html:52
msgid "Additional information"
msgstr "Informations supplémentaires"
#: re2o/templates/re2o/about.html:55
#: re2o/templates/re2o/about.html:57
msgid ""
"Re2o is an administration tool initiated by <a href=\"https://rezometz.org/"
"\">Rezo Metz</a> and a few members of other <a href=\"https://federez.net"
@ -175,35 +175,35 @@ msgstr ""
"développement, nous serons heureux de vous accueillir donc n'hésitez pas à "
"nous contacter et à venir nous aider à construire le futur de Re2o."
#: re2o/templates/re2o/about.html:74
#: re2o/templates/re2o/about.html:76
msgid "Contributors list"
msgstr "Liste des contributeurs"
#: re2o/templates/re2o/about.html:83
#: re2o/templates/re2o/about.html:85
msgid "Version information"
msgstr "Informations de versions"
#: re2o/templates/re2o/about.html:85
#: re2o/templates/re2o/about.html:87
#, python-format
msgid "<b>Remote URL</b>: %(git_info_remote)s"
msgstr "<b>URL distante</b> : %(git_info_remote)s"
#: re2o/templates/re2o/about.html:88
#: re2o/templates/re2o/about.html:90
#, python-format
msgid "<b>Branch</b>: %(git_info_branch)s"
msgstr "<b>Branche</b> : %(git_info_branch)s"
#: re2o/templates/re2o/about.html:91
#: re2o/templates/re2o/about.html:93
#, python-format
msgid "<b>Commit</b>: %(git_info_commit)s"
msgstr "<b>Commit</b> : %(git_info_commit)s"
#: re2o/templates/re2o/about.html:94
#: re2o/templates/re2o/about.html:96
#, python-format
msgid "<b>Commit date</b>: %(git_info_commit_date)s"
msgstr "<b>Date du commit</b> : %(git_info_commit_date)s"
#: re2o/templates/re2o/about.html:99
#: re2o/templates/re2o/about.html:101
msgid "Dependencies"
msgstr "Dépendances"
@ -217,7 +217,7 @@ msgstr "Effectuée par"
#: re2o/templates/re2o/aff_history.html:35
msgid "Edited"
msgstr ""
msgstr "Modifié"
#: re2o/templates/re2o/aff_history.html:36
msgid "Comment"
@ -225,15 +225,15 @@ msgstr "Commentaire"
#: re2o/templates/re2o/aff_history.html:48
msgid "Unknown"
msgstr ""
msgstr "Inconnu"
#: re2o/templates/re2o/aff_history.html:71
msgid "No event"
msgstr ""
msgstr "Pas d'évènement"
#: re2o/templates/re2o/aff_history.html:76
msgid "Related elements"
msgstr ""
msgstr "Éléments liés"
#: re2o/templates/re2o/aff_history.html:82 re2o/templates/re2o/history.html:30
msgid "History"
@ -249,10 +249,9 @@ msgid "Contact the organisation %(asso_name)s"
msgstr "Contacter l'association %(asso_name)s"
#: re2o/templates/re2o/history.html:33
#, fuzzy, python-format
#| msgid "History of %(object)s"
#, python-format
msgid "History of %(title)s"
msgstr "Historique de %(object)s"
msgstr "Historique de %(title)s"
#: re2o/templates/re2o/index.html:30
msgid "Home"
@ -329,16 +328,14 @@ msgstr "Tweets de @%(twitter_account_name)s"
msgid "Follow @%(twitter_account_name)s"
msgstr "Suivre @%(twitter_account_name)s"
#: re2o/templatetags/massive_bootstrap_form.py:413
msgid "Nothing"
msgstr "Rien"
#: re2o/urls.py:57
msgid "Homepage"
msgstr "Page d'accueil"
#: re2o/views.py:96
#: re2o/views.py:110 re2o/views.py:121
msgid "Unable to get the information."
msgstr "Impossible d'obtenir l'information."
#~ msgid "Next"
#~ msgstr "Suivant"
#~ msgid "Previous"
#~ msgstr "Précédent"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2018-06-24 20:10+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"

View file

@ -1,3 +1,15 @@
.navbar-collapse {
overflow-x: hidden;
}
/* For the footer to be at the bottom*/
body {
padding-top: 50px;
}
.content {
min-height: calc(100vh - 100px);
}
/* Footer */
footer {
padding-top: 3rem;
@ -70,10 +82,56 @@ a > i.fa {
}
/* Set gray background color */
.sidenav {
background-color: #f1f1f1;
border: 1px solid #e0e0e0;
border-radius: 0 0 5px 5px;
@media (min-width: 768px) {
.sidenav-right {
position: fixed;
top:50px;
right:0;
overflow-y: auto;
bottom:50px;
}
.sidenav-left {
position: fixed;
top:50px;
left:0;
overflow-y: auto;
bottom:50px;
}
.dropdown-menu .dropdown-toggle:after {
border-top: .3em solid transparent;
border-right: 0;
border-bottom: .3em solid transparent;
border-left: .3em solid;
}
.dropdown-menu .dropdown-menu {
margin-left: 0;
margin-right: 0;
}
.dropdown-menu li {
position: relative;
}
.nav-item .submenu {
display: none;
position: absolute;
left: 100%;
top: -7px;
}
.nav-item .submenu-left {
right: 100%;
left: auto;
}
.dropdown-menu>li:hover {
background-color: #f1f1f1
}
.dropdown-menu>li:hover>.submenu {
display: block;
}
}
.table > tbody > tr > td, .table > tbody > tr > th, .table > tfoot > tr > td, .table > tfoot > tr > th, .table > thead > tr > td, .table > thead > tr > th {
vertical-align: middle;
@ -148,3 +206,11 @@ dl.profile-info > div {
[data-toggle~="collapse"] {
cursor: pointer;
}
/* Indent for submenu when collapsed */
@media (max-width:767px) {
.submenu > li {
margin-left:20px;
}
};

View file

42
static/js/main.js Normal file
View file

@ -0,0 +1,42 @@
function adjustHeader(){
/* This function is here to adjust the header if the header navbar
goes into two lines. This can't happen if the width is sm or less,
and we shouldn't adjust in this case. */
if ($(window).width() >= 768) {
$('body').css('padding-top', $("#navbar-header").height());
$('.sidenav-left').css('top', $("#navbar-header").height());
} else {
$('body').css('padding-top', '');
$('.sidenav-left').css('top', '');
}
}
function listenSubmenu() {
/* Add listeners on sm screen or less for submenus. */
if ($(window).width() < 767) {
$('.dropdown-menu a').click(function (e) {
if ($(this).next('.submenu').length) {
e.preventDefault();
$(this).next('.submenu').toggle();
}
$('.dropdown').on('hide.bs.dropdown', function () {
$(this).find('.submenu').hide();
})
});
}
}
/* We need to apply those functions at init and when the screen is resized. */
$(window).resize(function () {
adjustHeader();
listenSubmenu();
});
adjustHeader();
listenSubmenu();
$(document).on('click', '.dropdown-menu', function (e) {
e.stopPropagation();
});

View file

@ -3,8 +3,8 @@ Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@ the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
@ -32,327 +32,90 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% self_adhesion as var_sa %}
<!DOCTYPE html>
<html lang="fr">
<head prefix="og: http://ogp.me/ns#">
{# Open Graph for social media #}
<meta property="og:title" content="{{ name_website }}" />
<meta property="og:type" content="website" />
<meta property="og:url" content="{{ request.scheme }}://{{ request.get_host }}/" />
<meta property="og:image" content="{% static 'images/logo_re2o.svg' %}"/>
<meta property="og:image:type" content="image/svg"/>
<meta property="og:image:alt" content="The Re2o logo"/>
<meta property="og:description" content="Networking managing website endorsed by FedeRez." />
{# Preload JavaScript #}
{% bootstrap_javascript %}
<script src="/static/js/typeahead/typeahead.js"></script>
<script src="/static/js/bootstrap-tokenfield/bootstrap-tokenfield.js"></script>
<script src="{% static 'js/collapse-from-url.js' %}"></script>
<head prefix="og: http://ogp.me/ns#">
{# Open Graph for social media #}
<meta property="og:title" content="{{ name_website }}" />
<meta property="og:type" content="website" />
<meta property="og:url" content="{{ request.scheme }}://{{ request.get_host }}/" />
<meta property="og:image" content="{% static 'images/logo_re2o.svg' %}" />
<meta property="og:image:type" content="image/svg" />
<meta property="og:image:alt" content="The Re2o logo" />
<meta property="og:description" content="Networking managing website endorsed by FedeRez." />
{% block custom_js %}{% endblock %}
{# Preload JavaScript #}
{% bootstrap_javascript %}
<script src="/static/js/typeahead/typeahead.js"></script>
<script src="/static/js/bootstrap-tokenfield/bootstrap-tokenfield.js"></script>
<script src="{% static 'js/collapse-from-url.js' %}"></script>
{# Load CSS #}
{% bootstrap_css %}
<link href="{% static 'css/typeaheadjs.css' %}" rel="stylesheet">
<link href="{% static 'css/bootstrap-tokenfield.css' %}" rel="stylesheet">
<link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet">
<link href="{% static 'css/base.css' %}" rel="stylesheet">
{% block custom_js %}{% endblock %}
{# Favicon with iOS, Android, touchbar support #}
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon/apple-touch-icon.png' %}">
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'favicon/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'favicon/favicon-16x16.png' %}">
<link rel="manifest" href="{% static 'favicon/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'favicon/safari-pinned-tab.svg' %}" color="#5bbad5">
<link rel="shortcut icon" href="{% static 'favicon/favicon.ico' %}">
<meta name="theme-color" content="#ffffff">
{# Load CSS #}
{% bootstrap_css %}
<link href="{% static 'css/typeaheadjs.css' %}" rel="stylesheet">
<link href="{% static 'css/bootstrap-tokenfield.css' %}" rel="stylesheet">
<link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet">
{# load theme #}
{% if request.user.is_authenticated %}
<link href="{% static 'css/themes/' %}{{request.user.theme}}" rel="stylesheet">
{% else %}
<link href="{% static 'css/themes/default.css' %}" rel="stylesheet">
{% endif %}
<link href="{% static 'css/base.css' %}" rel="stylesheet">
{# Do not allow zooming on devices #}
<meta name="viewport" content="width=device-width, initial-scale=1">
{# Favicon with iOS, Android, touchbar support #}
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon/apple-touch-icon.png' %}">
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'favicon/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'favicon/favicon-16x16.png' %}">
<link rel="manifest" href="{% static 'favicon/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'favicon/safari-pinned-tab.svg' %}" color="#5bbad5">
<link rel="shortcut icon" href="{% static 'favicon/favicon.ico' %}">
<meta name="theme-color" content="#ffffff">
<title>{{ name_website }} : {% block title %}{% trans "Home" %}{% endblock %}</title>
</head>
{# Do not allow zooming on devices #}
<meta name="viewport" content="width=device-width, initial-scale=1">
<body id="main">
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<img src="{% static 'images/logo_re2o_navbar.svg' %}" height=32>
{{ name_website }}
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
{% can_view_any_app users machines cotisations %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-users"></i> {% trans "Users" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
{% can_view_app users %}
<li><a href="{% url 'users:index' %}"><i class="fa fa-user"></i> {% trans "Manage the users" %}</a></li>
<li><a href="{% url 'users:index-clubs' %}"><i class="fa fa-users"></i> {% trans "Manage the clubs" %}</a></li>
{% acl_end %}
{% can_view_app machines %}
<li><a href="{% url 'machines:index' %}"><i class="fa fa-desktop"></i> {% trans "Manage the machines" %}</a></li>
{% acl_end %}
{% can_view_app cotisations %}
<li><a href="{% url 'cotisations:index' %}"><i class="fa fa-eur"></i> {% trans "Manage the subscriptions" %}</a></li>
{% acl_end %}
<title>{{ name_website }} : {% block title %}{% trans "Home" %}{% endblock %}</title>
</head>
{% for app, template in optionnal_templates_navbar_user_list %}
{% if app != 'topologie' %}
{{ template }}
{% endif %}
{% endfor %}
</ul>
</li>
{% acl_end %}
{% can_view_app topologie %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-sitemap"></i> {% trans "Topology" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'topologie:index' %}"><i class="fa fa-microchip"></i> {% trans "Switches" %}</a></li>
<li><a href="{% url 'topologie:index-ap' %}"><i class="fa fa-wifi"></i> {% trans "Access points" %}</a></li>
<li><a href="{% url 'topologie:index-room' %}"><i class="fa fa-home"></i> {% trans "Rooms" %}</a></li>
{% for app, template in optionnal_templates_navbar_user_list %}
{% if app == 'topologie' %}
{{ template }}
{% endif %}
{% endfor %}
</ul>
</li>
{% acl_end %}
{% can_view_app logs %}
<li><a href="{% url 'logs:index' %}"><i class="fa fa-area-chart"></i> {% trans "Statistics" %}</a></li>
{% acl_end %}
{% can_view_app preferences %}
<li>
<a href="{% url 'preferences:display-options' %}">
<i class="fa fa-cogs"></i> {% trans "Administration" %}
</a>
</li>
{% acl_end %}
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-info"></i> {% trans "Information and contact" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'about' %}"><i class="fa fa-info-circle"></i> {% trans "About" %}</a></li>
<li><a href="{% url 'contact' %}"><i class="fa fa-at"></i> {% trans "Contact" %}</a></li>
{% comment %}
<li><a href="{% url 'tickets:new-ticket' %}"><i class="fa fa-ticket"></i> {% trans "Open a ticket" %}</a><li>
{% endcomment %}
</ul>
</li>
{% if not request.user.is_authenticated %}
{% for template in optionnal_templates_navbar_logout_list %}
{{ template }}
{% endfor %}
{% if var_sa %}
<li>
<a href="{% url 'users:new-user' %}">
<i class="fa fa-user-plus"></i> {% trans "Sign up" %}
</a>
</li>
{% endif %}
<li>
<a id="toggle_login" href="{% url 'login' %}">
<i class="fa fa-sign-in"></i> {% trans "Log in" %}
</a>
</li>
{% else %}
{% can_view_any_app users machines cotisations %}
<li>
<form action="{% url 'search:search' %}" class="navbar-form" role="search">
<div class="input-group">
<input type="text" class="form-control" placeholder="{% trans "Search" %}" name="q" id="search-term" {% if search_term %}value="{{ search_term }}"{% endif %}>
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
<a href="{% url 'search:searchp' %}" class="btn btn-default" role="button"><i class="fa fa-plus"></i></a>
</div>
</div>
</form>
</li>
{% acl_end %}
{% endif %}
{% if request.user.is_authenticated %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-user-circle"></i> {{ request.user.pseudo|slice:":15" }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'users:mon-profil' %}"><i class="fa fa-user"></i> {% trans "My profile" %}</a></li>
<li><a id="toggle_login" href="{% url 'logout' %}"><i class="fa fa-sign-out"></i> {% trans "Log out" %}</a></li>
</ul>
</li>
{% endif %}
<li>
{% include 'buttons/setlang.html' %}
</li>
</ul>
</div>
<body id="main">
{% include 'nav.html' %}
<div class="container-fluid text-center content">
<div class="row content">
<div class="col-sm-2 sidenav-left pt4">
{% include 'sidebar.html' %}
{% block sidebar %}
{% endblock %}
</div>
</nav>
<div class="container-fluid text-center">
<div class="row content">
<div class="col-sm-2 sidenav pt4">
<div class="panel panel-default">
<div class="text-left list-group">
{% block sidebar %}
{% endblock %}
</div>
</div>
</div>
<div class="col-sm-8 text-left pt4">
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{% block content %}{% endblock %}
</div>
<div class="col-sm-2 sidenav pt4">
<div class="panel panel-default">
{% if request_user.is_authenticated %}
<div class="panel-heading">
<h4>{{ request_user.name }} {{ request_user.surname }}</h4>
</div>
<table class="table visible-sm visible-md">
<tr>
<td>
<b>{% trans "Username" %}</b>
<br>
{{ request_user.pseudo }}
</td>
</tr>
<tr>
<td>
<b>{% trans "Room" %}</b>
<br>
{{ request_user.room }}
</td>
</tr>
<tr>
<td>
<b>{% trans "Internet access" %}</b>
<br>
{% if request_user.has_access %}
<i class="text-success">{% blocktrans with end_access_date=request.user.end_access|date:"d b Y" %}Until {{ end_access_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Disabled" %}</i>
{% endif %}
</td>
</tr>
<tr>
<td>
<b>{% trans "Membership" %}</b>
<br>
{% if request_user.is_adherent %}
<i class="text-success">{% blocktrans with end_adhesion_date=request_user.end_adhesion|date:"d b Y" %}Until {{ end_adhesion_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Non member" %}</i>
{% endif %}
</td>
</tr>
</table>
<table class="table visible-xs visible-lg">
<tr>
<th scope="row">{% trans "Username" %}</th>
<td class="text-right">{{ request_user.pseudo }}</td>
</tr>
<tr>
<th scope="row">{% trans "Room" %}</th>
<td class="text-right">{{ request_user.room }}</td>
</tr>
<tr>
<th scope="row">{% trans "Internet access" %}</th>
<td class="text-right">
{% if request_user.has_access %}
<i class="text-success">{% blocktrans with end_access_date=request.user.end_access|date:"d b Y" %}Until {{ end_access_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Disabled" %}</i>
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Membership" %}</th>
<td class="text-right">
{% if request_user.is_adherent %}
<i class="text-success">{% blocktrans with end_adhesion_date=request_user.end_adhesion|date:"d b Y" %}Until {{ end_adhesion_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Non member" %}</i>
{% endif %}
</td>
</tr>
</table>
<div class="list-group">
<a class="list-group-item list-group-item-info" role="button"href="{% url 'users:mon-profil' %}">
<i class="fa fa-user-circle"></i>
{% trans "View my profile" %}
</a>
</div>
{% else %}
<div class="panel-body">
<p>{% trans "You are not logged in." %}</p>
</div>
{% endif %}
</div>
{% if request_user.is_authenticated %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>{% blocktrans count interfaces|length as nb %}{{ nb }} active machine{% plural %}{{ nb }} active machines{% endblocktrans %}</h4>
</div>
<ul class="list-group">
{% for interface in interfaces|slice:":5" %}
<div class="list-group-item" style="word-break: break-all">{{ interface }}</div>
{% endfor %}
{% if interfaces|length > 5 %}
<a class="list-group-item list-group-item-info" role="button" href="{% url 'users:mon-profil' %}">
<i class="fa fa-plus"></i>
{% trans "View my machines" %}
</a>
{% endif %}
</ul>
</div>
{% endif %}
</div>
<div class="col-sm-offset-2 col-sm-10 col-lg-8 text-left pt4">
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{% block content %}{% endblock %}
</div>
<div class="col-lg-2 pt4">
</div>
</div>
</div>
<footer class="text-muted">
<div class="container">
<p class="pull-right">
<a href="#">{% trans "Back to top" %}</a>
</p>
<p>{{ name_website }} {% trans "powered by" %} Re2o 2016&ndash;2020</p>
<p>
{% blocktrans trimmed %}
Brought to you with <i class="fa fa-heart text-danger"></i>.
{% endblocktrans %}
<a href="{{ request.scheme }}://{{ request.get_host }}/about/">{% trans "About this website" %}</a>.
</p>
<p>
{% blocktrans trimmed %}
This software is under the terms of the
<a href="http://www.gnu.org/licenses/gpl-2.0.txt" target="_blank" rel="nofollow">GPLv2</a> License.
{% endblocktrans %}
</p>
</div>
</footer>
{% include 'footer.html' %}
{# Load JavaScript #}
<script src="/static/js/konami/konami.js"></script>
<script src="/static/js/sapphire.js"></script>
<script>
// Konami activate sapphire
let s = Sapphire();
Konami(s.activate);
</script>
{% if request.user.shortcuts_enabled %}
<script src="/static/js/shortcuts.js"></script>
{% endif %}
{# Read the documentation for more information #}
</body>
</html>
{# Load JavaScript #}
<script src="/static/js/konami/konami.js"></script>
<script src="/static/js/sapphire.js"></script>
<script>
// Konami activate sapphire
let s = Sapphire();
Konami(s.activate);
</script>
{% if request.user.shortcuts_enabled %}
<script src="/static/js/shortcuts.js"></script>
{% endif %}
{# Read the documentation for more information #}
<script src="/static/js/main.js"></script>
</body>
</html>

53
templates/footer.html Normal file
View file

@ -0,0 +1,53 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load i18n %}
{% load static %}
<nav class="navbar navbar-default navbar-static-bottom">
<div class="container-fluid">
<p class="navbar-text">{{ name_website }} {% trans "powered by" %} Re2o 2016&ndash;2020.
{% blocktrans trimmed %}
Brought to you with <i class="fa fa-heart text-danger"></i>.
{% endblocktrans %}</p>
<ul class="nav navbar-nav">
<li>
<a href="{% url 'about' %}">
<i class="fa fa-info-circle"></i> {% trans "About" %}
</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="#">
<i class="fa fa-arrow-up"></i> {% trans "Top" %}
</a>
</li>
<p class="navbar-text">{% blocktrans trimmed %}
This software is under the terms of the
<a href="http://www.gnu.org/licenses/gpl-2.0.txt" target="_blank" rel="nofollow">GPLv2</a>
License.
{% endblocktrans %}</p>
</ul>
</div>
</nav>

View file

@ -21,20 +21,20 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Last-Translator: Yoann Piétri <me@nanoy.fr>\n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: templates/admin/base_site.html:65 templates/base.html:293
#: templates/admin/base_site.html:65 templates/footer.html:28
msgid "powered by"
msgstr "propulsé par"
#: templates/admin/base_site.html:69 templates/base.html:301
#: templates/admin/base_site.html:69 templates/footer.html:45
msgid ""
"This software is under the terms of the <a href=\"http://www.gnu.org/"
"licenses/gpl-2.0.txt\" target=\"_blank\" rel=\"nofollow\">GPLv2</a> License."
@ -70,17 +70,17 @@ msgstr "Mon compte"
#: templates/admin/custom_index.html:29
msgid "Recent actions"
msgstr ""
msgstr "Actions récentes"
#: templates/admin/custom_index.html:33
msgid "None available"
msgstr ""
msgstr "Non disponible"
#: templates/admin/custom_index.html:48
msgid "Unknown content"
msgstr ""
msgstr "Contenu incconu"
#: templates/base.html:72 templates/registration/logged_out.html:11
#: templates/base.html:79 templates/registration/logged_out.html:11
#: templates/registration/password_change_done.html:11
#: templates/registration/password_change_form.html:11
#: templates/registration/password_reset_complete.html:11
@ -88,153 +88,11 @@ msgstr ""
#: templates/registration/password_reset_done.html:11
#: templates/registration/password_reset_form.html:11
msgid "Home"
msgstr ""
#: templates/base.html:93
msgid "Users"
msgstr "Utilisateurs"
#: templates/base.html:96
msgid "Manage the users"
msgstr "Gérer les utilisateurs"
#: templates/base.html:97
msgid "Manage the clubs"
msgstr "Gérer les clubs"
#: templates/base.html:100
msgid "Manage the machines"
msgstr "Gérer les machines"
#: templates/base.html:103
msgid "Manage the subscriptions"
msgstr "Gérer les cotisations"
#: templates/base.html:116
msgid "Topology"
msgstr "Topologie"
#: templates/base.html:118
msgid "Switches"
msgstr "Commutateurs réseau"
#: templates/base.html:119
msgid "Access points"
msgstr "Points d'accès sans fil"
#: templates/base.html:120
msgid "Rooms"
msgstr "Chambres"
#: templates/base.html:130
msgid "Statistics"
msgstr "Statistiques"
#: templates/base.html:135
msgid "Administration"
msgstr ""
#: templates/base.html:142
msgid "Information and contact"
msgstr "Informations et contact"
#: templates/base.html:144
msgid "About"
msgstr "À propos"
#: templates/base.html:145
msgid "Contact"
msgstr "Contact"
#: templates/base.html:159
msgid "Sign up"
msgstr "S'inscrire"
#: templates/base.html:165 templates/registration/login.html:29
#: templates/registration/login.html:36
msgid "Log in"
msgstr ""
#: templates/base.html:173
msgid "Search"
msgstr ""
#: templates/base.html:187
msgid "My profile"
msgstr "Mon profil"
#: templates/base.html:188
msgid "Log out"
msgstr ""
#: templates/base.html:226
msgid "Username"
msgstr "Pseudo"
#: templates/base.html:230
msgid "Room"
msgstr "Chambre"
#: templates/base.html:234
msgid "Internet access"
msgstr "Accès Internet"
#: templates/base.html:237
#, python-format
msgid "Until %(end_access_date)s"
msgstr "Jusqu'au %(end_access_date)s"
#: templates/base.html:239
msgid "Disabled"
msgstr "Désactivé"
#: templates/base.html:244
msgid "Membership"
msgstr "Adhésion"
#: templates/base.html:247
#, python-format
msgid "Until %(end_adhesion_date)s"
msgstr "Jusqu'au %(end_adhesion_date)s"
#: templates/base.html:249
msgid "Non member"
msgstr "Non adhérent"
#: templates/base.html:257
msgid "View my profile"
msgstr "Voir mon profil"
#: templates/base.html:262
msgid "You are not logged in."
msgstr "Vous n'êtes pas connecté."
#: templates/base.html:269
#, python-format
msgid "%(nb)s active machine"
msgid_plural "%(nb)s active machines"
msgstr[0] "%(nb)s machine active"
msgstr[1] "%(nb)s machines actives"
#: templates/base.html:278
msgid "View my machines"
msgstr "Voir mes machines"
#: templates/base.html:291
msgid "Back to top"
msgstr "Retour en haut"
#: templates/base.html:295
msgid "Brought to you with <i class=\"fa fa-heart text-danger\"></i>."
msgstr "Codé avec <i class=\"fa fa-heart text-danger\"></i>."
#: templates/base.html:298
msgid "About this website"
msgstr "À propos de ce site"
msgstr "Acceuil"
#: templates/buttons/add.html:27
msgid "Add"
msgstr ""
msgstr "Ajouter"
#: templates/buttons/edit.html:27
msgid "Edit"
@ -242,7 +100,7 @@ msgstr "Modifier"
#: templates/buttons/history.html:27 templates/buttons/history.html:28
msgid "History"
msgstr ""
msgstr "Historique"
#: templates/buttons/setlang.html:34
msgid "Translation in development"
@ -258,7 +116,11 @@ msgstr "Tri décroissant"
#: templates/buttons/suppr.html:27
msgid "Delete"
msgstr ""
msgstr "Supprimer"
#: templates/buttons/view.html:25
msgid "View"
msgstr "Voir"
#: templates/errors/404.html:39
msgid "404 error: page not found"
@ -339,6 +201,239 @@ msgstr "Si vous n'avez aucune idée de ce que vous avez fait :"
msgid "Go back to a safe page"
msgstr "Retourner à une page sécurisée"
#: templates/footer.html:29
msgid "Brought to you with <i class=\"fa fa-heart text-danger\"></i>."
msgstr "Codé avec <i class=\"fa fa-heart text-danger\"></i>."
#: templates/footer.html:35
msgid "About"
msgstr "À propos"
#: templates/footer.html:42
msgid "Top"
msgstr "En haut"
#: templates/nav.html:45 templates/nav.html:52 templates/nav.html:207
msgid "Users"
msgstr "Utilisateurs"
#: templates/nav.html:49
msgid "Users and clubs"
msgstr "Utilisateurs et Clubs"
#: templates/nav.html:55
msgid "Clubs"
msgstr "Clubs"
#: templates/nav.html:58
msgid "Whitelists"
msgstr "Accès gracieux"
#: templates/nav.html:61
msgid "Bans"
msgstr "Banissements"
#: templates/nav.html:64
msgid "Massively archive"
msgstr "Archivage de masse"
#: templates/nav.html:70
msgid "Machines"
msgstr "Machines"
#: templates/nav.html:75
msgid "Groups"
msgstr "Groupes"
#: templates/nav.html:76 templates/nav.html:119
msgid "Advanced"
msgstr "Avancé"
#: templates/nav.html:81
msgid "Schools"
msgstr "Écoles"
#: templates/nav.html:84
msgid "Shells"
msgstr "Interfaces en ligne de commande"
#: templates/nav.html:99
msgid "Treasury"
msgstr "Trésorerie"
#: templates/nav.html:102 templates/nav.html:109
msgid "Invoices"
msgstr "Factures"
#: templates/nav.html:106
msgid "Control invoices"
msgstr "Contrôler les factures"
#: templates/nav.html:112
msgid "Cutsom invoices"
msgstr "Facture personnalisée"
#: templates/nav.html:117
msgid "Cost estimates"
msgstr "Devis"
#: templates/nav.html:124
msgid "Banks"
msgstr "Banques"
#: templates/nav.html:127
msgid "Articles"
msgstr "Articles"
#: templates/nav.html:130
msgid "Payment methods"
msgstr "Moyens de paiement"
#: templates/nav.html:144
msgid "Topology"
msgstr "Topologie"
#: templates/nav.html:147 templates/nav.html:151
msgid "Switches"
msgstr "Commutateurs réseau"
#: templates/nav.html:154
msgid "Switch models"
msgstr "Modèles de commutateurs réseau"
#: templates/nav.html:157
msgid "Switch modules"
msgstr "Modules de commutateurs réseau"
#: templates/nav.html:159
msgid "Switch bays"
msgstr "Baies de commutateurs réseau"
#: templates/nav.html:161
msgid "Stacks"
msgstr "Pile de commutateurs réseau"
#: templates/nav.html:164
msgid "Port profiles"
msgstr "Profils de port"
#: templates/nav.html:168
msgid "Infrastructure"
msgstr "Infrastructure"
#: templates/nav.html:172
msgid "Dormitories"
msgstr "Résidences"
#: templates/nav.html:174
msgid "Buildings"
msgstr "Bâtiments"
#: templates/nav.html:177
msgid "Rooms"
msgstr "Chambres"
#: templates/nav.html:181
msgid "Access points"
msgstr "Points d'accès sans fil"
#: templates/nav.html:194
msgid "Statistics"
msgstr "Statistiques"
#: templates/nav.html:197
msgid "Summary"
msgstr "Résumé"
#: templates/nav.html:199
msgid "Events"
msgstr "Évènements"
#: templates/nav.html:201 templates/nav.html:226
msgid "General"
msgstr "Général"
#: templates/nav.html:203
msgid "Database"
msgstr "Base de données"
#: templates/nav.html:205
msgid "Wiring actions"
msgstr "Actions de cablage"
#: templates/nav.html:209
msgid "Machine history"
msgstr "Historique machine"
#: templates/nav.html:221
msgid "Administration"
msgstr "Administration"
#: templates/nav.html:231
msgid "LDAP service users"
msgstr "Utilisateurs service LDAP"
#: templates/nav.html:236
msgid "Services"
msgstr "Services"
#: templates/nav.html:239
msgid "Machine types"
msgstr "Types de machines"
#: templates/nav.html:241
msgid "Network"
msgstr "Réseau"
#: templates/nav.html:245
msgid "IP ranges"
msgstr "Blocs IP"
#: templates/nav.html:248
msgid "VLANs"
msgstr "VLANs"
#: templates/nav.html:251
msgid "Extensions and zones"
msgstr "Zones et extensions"
#: templates/nav.html:254
msgid "NAS"
msgstr "NAS"
#: templates/nav.html:257
msgid "Server roles"
msgstr "Roles de serveurs"
#: templates/nav.html:260
msgid "Ports openings"
msgstr "Ouvertures de ports"
#: templates/nav.html:269
msgid "Contact"
msgstr "Contact"
#: templates/nav.html:277
msgid "Sign up"
msgstr "S'inscrire"
#: templates/nav.html:283 templates/registration/login.html:29
#: templates/registration/login.html:36
msgid "Log in"
msgstr "Se connecter"
#: templates/nav.html:291
msgid "Search"
msgstr "Chercher"
#: templates/nav.html:310
msgid "My profile"
msgstr "Mon profil"
#: templates/nav.html:312
msgid "Log out"
msgstr "Se déconnecter"
#: templates/pagination.html:35
msgid "First"
msgstr "Première page"
@ -357,11 +452,11 @@ msgstr "Dernière page"
#: templates/registration/logged_out.html:16
msgid "Thanks for spending some quality time with the Web site today."
msgstr ""
msgstr "Merci pour avoir passé un moment de qualite sur notre site aujourd'hui."
#: templates/registration/logged_out.html:17
msgid "Log in again"
msgstr ""
msgstr "Se reconnecter"
#: templates/registration/login.html:40
msgid "Forgotten password?"
@ -370,17 +465,17 @@ msgstr "Mot de passe oublié ?"
#: templates/registration/password_change_done.html:11
#: templates/registration/password_change_form.html:11
msgid "Password change"
msgstr ""
msgstr "Modification du mot de passe"
#: templates/registration/password_reset_complete.html:11
#: templates/registration/password_reset_done.html:11
#: templates/registration/password_reset_form.html:11
msgid "Password reset"
msgstr ""
msgstr "Réinitialisation du mot de passe"
#: templates/registration/password_reset_confirm.html:11
msgid "Password reset confirmation"
msgstr ""
msgstr "Confirmation de la réinitialisation du mot de passe"
#: templates/registration/password_reset_email.html:2
#, python-format
@ -388,16 +483,74 @@ msgid ""
"You're receiving this email because you requested a password reset for your "
"user account at %(site_name)s."
msgstr ""
"Vous recevez cet email car vous avez demandé une réinitialisation du mot de passe "
"de votre compte sur %(site_name)s."
#: templates/registration/password_reset_email.html:4
msgid "Please go to the following page and choose a new password:"
msgstr ""
msgstr "Merci de vous rendre sur la page suivante et de choisir un nouveau mot de passe : "
#: templates/registration/password_reset_email.html:9
msgid "Thanks for using our site!"
msgstr ""
msgstr "Merci d'utiliser notre site !"
#: templates/registration/password_reset_email.html:11
#, python-format
msgid "The %(site_name)s team"
msgstr ""
msgstr "L'équipe de %(site_name)s"
#: templates/sidebar.html:34 templates/sidebar.html:74
msgid "Username"
msgstr "Pseudo"
#: templates/sidebar.html:41 templates/sidebar.html:78
msgid "Room"
msgstr "Chambre"
#: templates/sidebar.html:48 templates/sidebar.html:82
msgid "Internet access"
msgstr "Accès Internet"
#: templates/sidebar.html:51 templates/sidebar.html:85
msgid ""
"Until\n"
" %(end_access_date)s"
msgstr "Jusqu'au %(end_access_date)s"
#: templates/sidebar.html:54 templates/sidebar.html:88
msgid "Disabled"
msgstr "Désactivé"
#: templates/sidebar.html:60 templates/sidebar.html:93
msgid "Membership"
msgstr "Adhésion"
#: templates/sidebar.html:63 templates/sidebar.html:96
msgid ""
"Until\n"
" %(end_adhesion_date)s"
msgstr "Jusqu'au %(end_adhesion_date)s"
#: templates/sidebar.html:66 templates/sidebar.html:99
msgid "Non member"
msgstr "Non adhérent"
#: templates/sidebar.html:108
msgid "View my profile"
msgstr "Voir mon profil"
#: templates/sidebar.html:113
msgid "You are not logged in."
msgstr "Vous n'êtes pas connecté."
#: templates/sidebar.html:120
msgid "%(nb)s active machine"
msgid_plural ""
"%(nb)s\n"
" active machines"
msgstr[0] "%(nb)s machine active"
msgstr[1] "%(nb)s machines actives"
#: templates/sidebar.html:131
msgid "View my machines"
msgstr "Voir mes machines"

322
templates/nav.html Normal file
View file

@ -0,0 +1,322 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load static %}
{% load acl %}
{% load i18n %}
<nav class="navbar navbar-inverse navbar-fixed-top" id="navbar-header">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<img src="{% static 'images/logo_re2o_navbar.svg' %}" height=32>
{{ name_website }}
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
{% can_view_any_app users machines %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa fa-users"></i>
{% trans "Users" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
{% can_view_app users %}
<li><a class="dropdown-item" href="#"><i class="fa fa-users"></i>
{% trans "Users and clubs" %} &raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'users:index' %}"><i class="fa fa-user"></i>
{% trans "Users" %}</a></li>
<li><a class="dropdown-item" href="{% url 'users:index-clubs' %}"><i
class="fa fa-users"></i>
{% trans "Clubs" %}</a></li>
<li><a class="dropdown-item" href="{% url 'users:index-white' %}"><i
class="fa fa-user-plus"></i>
{% trans "Whitelists" %}</a></li>
<li><a class="dropdown-item" href="{% url 'users:index-ban' %}"><i
class="fa fa-user-times"></i>
{% trans "Bans" %}</a></li>
<li><a class="dropdown-item" href="{% url 'users:mass-archive' %}"><i
class="fa fa-archive"></i>
{% trans "Massively archive" %}</a></li>
</ul>
</li>
{% acl_end %}
{% can_view_app machines %}
<li><a class="dropdown-item" href="{% url 'machines:index' %}"><i class="fa fa-laptop"></i>
{% trans "Machines" %}</a></li>
{% acl_end %}
{% can_view_app users %}
<li><a class="dropdown-item" href="{% url 'users:index-listright' %}"><i
class="fa fa-object-group"></i>
{% trans "Groups" %}</a></li>
<li><a class="dropdown-item" href="#"><i class="fa fa-plus"></i> {% trans "Advanced" %}
&raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'users:index-school' %}"><i
class="fa fa-graduation-cap"></i>
{% trans "Schools" %}</a></li>
<li><a class="dropdown-item" href="{% url 'users:index-shell' %}"><i
class="fa fa-terminal"></i>
{% trans "Shells" %}</a></li>
</ul>
</li>
{% acl_end %}
{% for app, template in optionnal_templates_navbar_user_list %}
{% if app != 'cotisations' and app != 'topologie' and app != 'logs' %}
{{ template }}
{% endif %}
{% endfor %}
</ul>
</li>
{% acl_end %}
{% can_view_app cotisations %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa fa-eur"></i>
{% trans "Treasury" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fa fa-file"></i>
{% trans "Invoices" %} &raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'cotisations:control' %}"><i
class="fa fa-eye"></i>
{% trans "Control invoices" %}</a></li>
<li><a class="dropdown-item" href="{% url 'cotisations:index' %}"><i
class="fa fa-file"></i>
{% trans "Invoices" %}</a></li>
<li><a class="dropdown-item" href="{% url 'cotisations:index-custom-invoice' %}"><i
class="fa fa-file-text"></i>
{% trans "Cutsom invoices" %}</a></li>
</ul>
</li>
<li><a class="dropdown-item" href="{% url 'cotisations:index-cost-estimate' %}"><i
class="fa fa-files-o"></i>
{% trans "Cost estimates" %}</a></li>
<li><a class="dropdown-item" href="#"><i class="fa fa-money"></i>
{% trans "Advanced" %}
&raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'cotisations:index-banque' %}"><i
class="fa fa-bank"></i>
{% trans "Banks" %}</a></li>
<li><a class="dropdown-item" href="{% url 'cotisations:index-article' %}"><i
class="fa fa-barcode"></i>
{% trans "Articles" %}</a></li>
<li><a class="dropdown-item" href="{% url 'cotisations:index-paiement' %}"><i
class="fa fa-credit-card"></i>
{% trans "Payment methods" %}</a></li>
</ul>
</li>
{% for app, template in optionnal_templates_navbar_user_list %}
{% if app == 'cotisations' %}
{{ template }}
{% endif %}
{% endfor %}
</ul>
</li>
{% acl_end %}
{% can_view_app topologie %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa fa-sitemap"></i>
{% trans "Topology" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fa fa-microchip"></i>
{% trans "Switches" %} &raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'topologie:index' %}"><i
class="fa fa-microchip"></i>
{% trans "Switches" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-model-switch' %}"><i
class="fa fa-object-group"></i>
{% trans "Switch models" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-module' %}"><i
class="fa fa-puzzle-piece"></i>
{% trans "Switch modules" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-switch-bay' %}"><i class="fa fa-wrench"></i>
{% trans "Switch bays" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-stack' %}"><i class="fa fa-server"></i>
{% trans "Stacks" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-port-profile' %}"><i
class="fa fa-cog"></i>
{% trans "Port profiles" %}</a></li>
</ul>
</li>
<li><a class="dropdown-item" href="#"><i class="fa fa-building"></i>
{% trans "Infrastructure" %}
&raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'topologie:index-dormitory' %}"><i class="fa fa-bank"></i>
{% trans "Dormitories" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-building' %}"><i class="fa fa-home"></i>
{% trans "Buildings" %}</a></li>
<li><a class="dropdown-item" href="{% url 'topologie:index-room' %}"><i
class="fa fa-bed"></i>
{% trans "Rooms" %}</a></li>
</ul>
</li>
<li><a class="dropdown-item" href="{% url 'topologie:index-ap' %}"><i class="fa fa-wifi"></i>
{% trans "Access points" %}</a></li>
{% for app, template in optionnal_templates_navbar_user_list %}
{% if app == 'topologie' %}
{{ template }}
{% endif %}
{% endfor %}
</ul>
</li>
{% acl_end %}
{% can_view_app logs %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa fa-area-chart"></i>
{% trans "Statistics" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'logs:index' %}"><i class="fa fa-clipboard"></i>
{% trans "Summary" %}</a></li>
<li><a class="dropdown-item" href="{% url 'logs:stats-logs' %}"><i class="fa fa-calendar"></i>
{% trans "Events" %}</a></li>
<li><a class="dropdown-item" href="{% url 'logs:stats-general' %}"><i class="fa fa-area-chart"></i>
{% trans "General" %}</a></li>
<li><a class="dropdown-item" href="{% url 'logs:stats-models' %}"><i class="fa fa-database"></i>
{% trans "Database" %}</a></li>
<li><a class="dropdown-item" href="{% url 'logs:stats-users' %}"><i class="fa fa-plug"></i>
{% trans "Wiring actions" %}</a></li>
<li><a class="dropdown-item" href="{% url 'logs:stats-actions' %}"><i class="fa fa-users"></i>
{% trans "Users" %}</a></li>
<li><a class="dropdown-item" href="{% url 'logs:stats-search-machine' %}"><i class="fa fa-laptop"></i>
{% trans "Machine history" %}</a></li>
{% for app, template in optionnal_templates_navbar_user_list %}
{% if app == 'logs' %}
{{ template }}
{% endif %}
{% endfor %}
</ul>
</li>
{% acl_end %}
{% can_view_any_app preferences users machines %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa fa-cogs"></i>
{% trans "Administration" %}<span class="caret"></span></a>
<ul class="dropdown-menu">
{% can_view_app preferences %}
<li><a class="dropdown-item" href="{% url 'preferences:display-options' %}"><i
class="fa fa-cogs"></i>
{% trans "General" %}</a></li>
{% acl_end %}
{% can_view_app users %}
<li><a class="dropdown-item" href="{% url 'users:index-serviceusers' %}"><i
class="fa fa-address-book"></i>
{% trans "LDAP service users" %}</a></li>
{% acl_end %}
{% can_view_app machines %}
<li><a class="dropdown-item" href="{% url 'machines:index-service' %}"><i
class="fa fa-wrench"></i>
{% trans "Services" %}</a></li>
<li><a class="dropdown-item" href="{% url 'machines:index-machinetype' %}"><i
class="fa fa-laptop"></i>
{% trans "Machine types" %}</a></li>
<li><a class="dropdown-item" href="#"><i class="fa fa-globe"></i>
{% trans "Network" %} &raquo </a>
<ul class="submenu dropdown-menu">
<li><a class="dropdown-item" href="{% url 'machines:index-iptype' %}"><i
class="fa fa-ellipsis-h"></i>
{% trans "IP ranges" %}</a></li>
<li><a class="dropdown-item" href="{% url 'machines:index-vlan' %}"><i
class="fa fa-object-group"></i>
{% trans "VLANs" %}</a></li>
<li><a class="dropdown-item" href="{% url 'machines:index-extension' %}"><i
class="fa fa-wrench"></i>
{% trans "Extensions and zones" %}</a></li>
<li><a class="dropdown-item" href="{% url 'machines:index-nas' %}"><i
class="fa fa-certificate"></i>
{% trans "NAS" %}</a></li>
<li><a class="dropdown-item" href="{% url 'machines:index-role' %}"><i
class="fa fa-server"></i>
{% trans "Server roles" %}</a></li>
<li><a class="dropdown-item" href="{% url 'machines:index-portlist' %}"><i
class="fa fa-cog"></i>
{% trans "Ports openings" %}</a></li>
</ul>
</li>
{% acl_end %}
</ul>
</li>
{% acl_end %}
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'contact' %}"><i class="fa fa-at"></i> {% trans "Contact" %}</a>
{% if not request.user.is_authenticated %}
{% for template in optionnal_templates_navbar_logout_list %}
{{ template }}
{% endfor %}
{% if var_sa %}
<li>
<a href="{% url 'users:new-user' %}">
<i class="fa fa-user-plus"></i> {% trans "Sign up" %}
</a>
</li>
{% endif %}
<li>
<a id="toggle_login" href="{% url 'login' %}">
<i class="fa fa-sign-in"></i> {% trans "Log in" %}
</a>
</li>
{% else %}
{% can_view_any_app users machines cotisations %}
<li>
<form action="{% url 'search:search' %}" class="navbar-form" role="search">
<div class="input-group">
<input type="text" class="form-control" placeholder="{% trans "Search" %}" name="q"
id="search-term" {% if search_term %}value="{{ search_term }}" {% endif %}>
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
<a href="{% url 'search:searchp' %}" class="btn btn-default" role="button"><i
class="fa fa-plus"></i></a>
</div>
</div>
</form>
</li>
{% acl_end %}
{% endif %}
{% if request.user.is_authenticated %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false"><i class="fa fa-user-circle"></i>
{{ request.user.pseudo|slice:":15" }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="{% url 'users:mon-profil' %}"><i class="fa fa-user"></i>
{% trans "My profile" %}</a></li>
<li><a id="toggle_login" href="{% url 'logout' %}"><i class="fa fa-sign-out"></i>
{% trans "Log out" %}</a></li>
</ul>
</li>
{% endif %}
<li>
{% include 'buttons/setlang.html' %}
</li>
</ul>
</div>
</div>
</nav>

136
templates/sidebar.html Normal file
View file

@ -0,0 +1,136 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load i18n %}
<div class="panel panel-default">
{% if request_user.is_authenticated %}
<div class="panel-heading">
<h4>{{ request_user.name }} {{ request_user.surname }}</h4>
</div>
<table class="table visible-sm visible-md">
<tr>
<td>
<b>{% trans "Username" %}</b>
<br>
{{ request_user.pseudo }}
</td>
</tr>
<tr>
<td>
<b>{% trans "Room" %}</b>
<br>
{{ request_user.room }}
</td>
</tr>
<tr>
<td>
<b>{% trans "Internet access" %}</b>
<br>
{% if request_user.has_access %}
<i class="text-success">{% blocktrans with end_access_date=request.user.end_access|date:"d b Y" %}Until
{{ end_access_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Disabled" %}</i>
{% endif %}
</td>
</tr>
<tr>
<td>
<b>{% trans "Membership" %}</b>
<br>
{% if request_user.is_adherent %}
<i class="text-success">{% blocktrans with end_adhesion_date=request_user.end_adhesion|date:"d b Y" %}Until
{{ end_adhesion_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Non member" %}</i>
{% endif %}
</td>
</tr>
</table>
<table class="table visible-xs visible-lg">
<tr>
<th scope="row">{% trans "Username" %}</th>
<td class="text-right">{{ request_user.pseudo }}</td>
</tr>
<tr>
<th scope="row">{% trans "Room" %}</th>
<td class="text-right">{{ request_user.room }}</td>
</tr>
<tr>
<th scope="row">{% trans "Internet access" %}</th>
<td class="text-right">
{% if request_user.has_access %}
<i class="text-success">{% blocktrans with end_access_date=request.user.end_access|date:"d b Y" %}Until
{{ end_access_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Disabled" %}</i>
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Membership" %}</th>
<td class="text-right">
{% if request_user.is_adherent %}
<i class="text-success">{% blocktrans with end_adhesion_date=request_user.end_adhesion|date:"d b Y" %}Until
{{ end_adhesion_date }}{% endblocktrans %}</i>
{% else %}
<i class="text-danger">{% trans "Non member" %}</i>
{% endif %}
</td>
</tr>
</table>
<div class="list-group">
<a class="list-group-item list-group-item-info" role="button"
href="{% url 'users:mon-profil' %}">
<i class="fa fa-user-circle"></i>
{% trans "View my profile" %}
</a>
</div>
{% else %}
<div class="panel-body">
<p>{% trans "You are not logged in." %}</p>
</div>
{% endif %}
</div>
{% if request_user.is_authenticated %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>{% blocktrans count interfaces|length as nb %}{{ nb }} active machine{% plural %}{{ nb }}
active machines{% endblocktrans %}</h4>
</div>
<ul class="list-group">
{% for interface in interfaces|slice:":5" %}
<div class="list-group-item" style="word-break: break-all">{{ interface }}</div>
{% endfor %}
{% if interfaces|length > 5 %}
<a class="list-group-item list-group-item-info" role="button"
href="{% url 'users:mon-profil' %}">
<i class="fa fa-plus"></i>
{% trans "View my machines" %}
</a>
{% endif %}
</ul>
</div>
{% endif %}

23
themes/README.md Normal file
View file

@ -0,0 +1,23 @@
# Custom themes for Re2o
The following themes are licensed under MIT to Thomas Park. See https://bootswatch.com.
By default, only the default.css is enabled, which is a blank css file.
**How to activate new themes ?**
You can activate themes by copying them, or making a symbolic link to the `static/css/themes` directory and collecting the statics.
**How to change the default theme ?**
You can change the default theme by changing the default.css file.
**How to add new theme ?**
You can add a brand new theme by adding a css file to the `static/css/themes` directory and collecting the statics.
**What happens if I delete a theme ?**
User with this theme will continue to try to load this theme, without success if the theme was correctly deleted. It won't cause any malfunctions on the client side, and the default re2o theme (but not the default.css) theme will be loaded. Users will not be able to select this theme anymore afterwards.
Try to not delete the default.css theme.

11
themes/cerulan.css Normal file

File diff suppressed because one or more lines are too long

11
themes/cosmo.css Normal file

File diff suppressed because one or more lines are too long

11
themes/cyborg.css Normal file

File diff suppressed because one or more lines are too long

11
themes/darkly.css Normal file

File diff suppressed because one or more lines are too long

0
themes/default.css Normal file
View file

11
themes/flatly.css Normal file

File diff suppressed because one or more lines are too long

11
themes/journal.css Normal file

File diff suppressed because one or more lines are too long

11
themes/lumen.css Normal file

File diff suppressed because one or more lines are too long

11
themes/paper.css Normal file

File diff suppressed because one or more lines are too long

11
themes/readable.css Normal file

File diff suppressed because one or more lines are too long

11
themes/sandstone.css Normal file

File diff suppressed because one or more lines are too long

11
themes/simplex.css Normal file

File diff suppressed because one or more lines are too long

11
themes/slate.css Normal file

File diff suppressed because one or more lines are too long

11
themes/spacelab.css Normal file

File diff suppressed because one or more lines are too long

11
themes/superhero.css Normal file

File diff suppressed because one or more lines are too long

11
themes/united.css Normal file

File diff suppressed because one or more lines are too long

11
themes/yeti.css Normal file

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-17 12:49+0200\n"
"POT-Creation-Date: 2020-11-17 22:00+0100\n"
"PO-Revision-Date: 2019-11-16 00:35+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -34,61 +34,61 @@ msgstr ""
msgid "comment"
msgstr "commentaire"
#: tickets/models.py:59
#: tickets/models.py:75
msgid "Title of the ticket."
msgstr "Titre du ticket."
#: tickets/models.py:68
#: tickets/models.py:84
msgid "An email address to get back to you."
msgstr "Une adresse mail pour vous recontacter."
#: tickets/models.py:72
#: tickets/models.py:88
msgid "Language of the ticket."
msgstr "Langue des tickets"
#: tickets/models.py:77 tickets/models.py:174
#: tickets/models.py:93 tickets/models.py:204
msgid "Can view a ticket object"
msgstr "Peut voir un objet ticket"
#: tickets/models.py:78 tickets/models.py:175
#: tickets/models.py:94 tickets/models.py:205
msgid "ticket"
msgstr "ticket"
#: tickets/models.py:79 tickets/models.py:176
#: tickets/models.py:95 tickets/models.py:206
msgid "tickets"
msgstr "tickets"
#: tickets/models.py:83
#: tickets/models.py:99
#, python-brace-format
msgid "Ticket from {name}. Date: {date}."
msgstr "Ticket de {name}. Date : {date}."
#: tickets/models.py:85
#: tickets/models.py:101
#, python-format
msgid "Anonymous ticket. Date: %s."
msgstr "Ticket anonyme. Date : %s."
#: tickets/models.py:93 tickets/templates/tickets/aff_ticket.html:52
#: tickets/models.py:109 tickets/templates/tickets/aff_ticket.html:52
msgid "Anonymous user"
msgstr "Utilisateur anonyme"
#: tickets/models.py:131
#: tickets/models.py:150
msgid "You don't have the right to view other tickets than yours."
msgstr "Vous n'avez pas le droit de voir d'autres tickets que les vôtres."
#: tickets/models.py:143 tickets/models.py:218
#: tickets/models.py:162 tickets/models.py:248
msgid "You don't have the right to view the list of tickets."
msgstr "Vous n'avez pas le droit de voir la liste des tickets."
#: tickets/models.py:191
#: tickets/models.py:221
msgid "You don't have the right to view other tickets comments than yours."
msgstr "Vous n'avez pas le droit de voir d'autres tickets que les vôtres."
#: tickets/models.py:206
#: tickets/models.py:236
msgid "You don't have the right to edit other tickets comments than yours."
msgstr "Vous n'avez pas le droit d'éditer d'autres tickets que les vôtres."
#: tickets/models.py:237
#: tickets/models.py:269
msgid "Update of your ticket"
msgstr "Mise à jour de votre ticket"
@ -111,14 +111,24 @@ msgstr "Options des tickets"
msgid "Can view tickets options"
msgstr "Peut voir les options des tickets"
#: tickets/templates/tickets/aff_profil.html:6
#: tickets/templates/tickets/aff_ticket.html:32
#: tickets/templates/tickets/contact.html:4
#: tickets/templates/tickets/contact.html:8
#: tickets/templates/tickets/index.html:29
#: tickets/templates/tickets/preferences.html:6
#: tickets/templates/tickets/profil.html:6
msgid "Tickets"
msgstr "Tickets"
#: tickets/templates/tickets/aff_profil.html:12
#: tickets/templates/tickets/contact.html:11
#: tickets/templates/tickets/navbar_logout.html:4
msgid "Open a ticket"
msgstr "Ouvrir un ticket"
#: tickets/templates/tickets/aff_profil.html:19
msgid "No tickets"
msgstr "Pas de tickets"
#: tickets/templates/tickets/aff_ticket.html:36
#, python-format
msgid "Ticket #%(id)s"
@ -150,7 +160,7 @@ msgid "Add a comment "
msgstr "Ajouter un commentaire"
#: tickets/templates/tickets/aff_ticket.html:64
#: tickets/templates/tickets/preferences.html:14 tickets/views.py:153
#: tickets/templates/tickets/preferences.html:14 tickets/views.py:149
msgid "Edit"
msgstr "Modifier"
@ -228,7 +238,7 @@ msgstr "Date"
msgid "Anonymous"
msgstr "Anonyme"
#: tickets/templates/tickets/contact.html:8
#: tickets/templates/tickets/contact.html:17
#, python-format
msgid ""
"If you are experiencing issues with the services offered by %(asso_name)s, "
@ -240,12 +250,6 @@ msgstr ""
"voulez nous contacter pour n'importe quel autre sujet, veuillez choisir une "
"adresse ci-dessous."
#: tickets/templates/tickets/contact.html:10
#: tickets/templates/tickets/navbar_logout.html:4
#: tickets/templates/tickets/profil.html:12
msgid "Open a ticket"
msgstr "Ouvrir un ticket"
#: tickets/templates/tickets/delete.html:29
msgid "Deletion of tickets"
msgstr "Suppression de tickets"
@ -256,6 +260,8 @@ msgid ""
"Warning: are you sure you want to delete this %(objet_name)s object "
"( %(objet)s )?"
msgstr ""
"Attention: êtes-vous sûr de vouloir supprimer l'objet %(objet_name)s "
"( %(objet)s )?"
#: tickets/templates/tickets/delete.html:36
msgid "Confirm"
@ -311,42 +317,38 @@ msgstr "Adresse mail de publication"
msgid "No email address, the tickets will not be published."
msgstr "Pas d'adresse mail, les tickets ne seront pas publiés."
#: tickets/templates/tickets/profil.html:19
msgid "No tickets"
msgstr "Pas de tickets"
#: tickets/views.py:62
#: tickets/views.py:58
msgid ""
"Your ticket has been succesfully opened. We will take care of it as soon as "
"possible."
msgstr ""
"Votre ticket a bien été ouvert. Nous nous en occuperons dès que possible."
#: tickets/views.py:109
#: tickets/views.py:105
msgid "Ticket has been updated successfully"
msgstr "Le ticket a été mis à jour"
#: tickets/views.py:130
#: tickets/views.py:126
msgid "This comment was added."
msgstr "Le commentaire a été ajouté"
#: tickets/views.py:135
#: tickets/views.py:131
msgid "Add a comment"
msgstr "Ajouter un commentaire"
#: tickets/views.py:148
#: tickets/views.py:144
msgid "This comment was edited."
msgstr "Le commentaire a été édité"
#: tickets/views.py:164
#: tickets/views.py:160
msgid "The comment was deleted."
msgstr "Le commentaire a été supprimé"
#: tickets/views.py:169
#: tickets/views.py:165
msgid "Ticket Comment"
msgstr "Commentaire de ticket"
#: tickets/views.py:183 tickets/views.py:208
#: tickets/views.py:179 tickets/views.py:204
msgid "Never"
msgstr "Jamais"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,42 @@
{% extends 'topologie/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load bootstrap3 %}
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Topology" %}{% endblock %}
{% block content %}
<h2>{% trans "Buildings" %}</h2>
{% can_create Building %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-building' %}">
<i class="fa fa-plus"></i> {% trans "Add a building" %}
</a>
<hr>
{% acl_end %}
{% include 'topologie/aff_building.html' with building_list=building_list %}
{% endblock %}

View file

@ -30,33 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}{% trans "Topology" %}{% endblock %}
{% block content %}
<h2>{% trans "Stacks" %}</h2>
{% can_create Stack %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-stack' %}">
<i class="fa fa-plus"></i> {% trans "Add a stack" %}
</a>
{% acl_end %}
{% include 'topologie/aff_stacks.html' with stack_list=stack_list %}
<h2>{% trans "Switch bays" %}</h2>
{% can_create SwitchBay %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-switch-bay' %}">
<i class="fa fa-plus"></i> {% trans "Add a switch bay" %}
</a>
<hr>
{% acl_end %}
{% include 'topologie/aff_switch_bay.html' with switch_bay_list=switch_bay_list %}
<h2>{% trans "Buildings" %}</h2>
{% can_create Building %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-building' %}">
<i class="fa fa-plus"></i> {% trans "Add a building" %}
</a>
<hr>
{% acl_end %}
{% include 'topologie/aff_building.html' with building_list=building_list %}
<h2>{% trans "Dormitories" %}</h2>
{% can_create Dormitory %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-dormitory' %}">

View file

@ -0,0 +1,41 @@
{% extends 'topologie/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load bootstrap3 %}
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Topology" %}{% endblock %}
{% block content %}
<h2>{% trans "Stacks" %}</h2>
{% can_create Stack %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-stack' %}">
<i class="fa fa-plus"></i> {% trans "Add a stack" %}
</a>
{% acl_end %}
{% include 'topologie/aff_stacks.html' with stack_list=stack_list %}
{% endblock %}

View file

@ -0,0 +1,42 @@
{% extends 'topologie/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Lara Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load bootstrap3 %}
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Topology" %}{% endblock %}
{% block content %}
<h2>{% trans "Switch bays" %}</h2>
{% can_create SwitchBay %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-switch-bay' %}">
<i class="fa fa-plus"></i> {% trans "Add a switch bay" %}
</a>
<hr>
{% acl_end %}
{% include 'topologie/aff_switch_bay.html' with switch_bay_list=switch_bay_list %}
{% endblock %}

View file

@ -23,36 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load i18n %}
{% block sidebar %}
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index-room' %}">
<i class="fa fa-home"></i>
{% trans "Rooms and premises" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index' %}">
<i class="fa fa-microchip"></i>
{% trans "Switches" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index-module' %}">
<i class="fa fa-microchip"></i>
{% trans "Switch modules" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index-port-profile' %}">
<i class="fa fa-cogs"></i>
{% trans "Port profiles" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index-ap' %}">
<i class="fa fa-wifi"></i>
{% trans "Access points" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index-physical-grouping' %}">
<i class="fa fa-list-ul"></i>
{% trans "Physical grouping" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'topologie:index-model-switch' %}">
<i class="fa fa-list-ul"></i>
{% trans "Switch models and constructors" %}
</a>
{% endblock %}

View file

@ -49,9 +49,24 @@ urlpatterns = [
url(r"^edit_switch/(?P<switchid>[0-9]+)$", views.edit_switch, name="edit-switch"),
url(r"^new_stack/$", views.new_stack, name="new-stack"),
url(
r"^index_physical_grouping/$",
views.index_physical_grouping,
name="index-physical-grouping",
r"^index_stack/$",
views.index_stack,
name="index-stack",
),
url(
r"^index_switch_bay/$",
views.index_switch_bay,
name="index-switch-bay",
),
url(
r"^index_building/$",
views.index_building,
name="index-building",
),
url(
r"^index_dormitory/$",
views.index_dormitory,
name="index-dormitory",
),
url(r"^edit_stack/(?P<stackid>[0-9]+)$", views.edit_stack, name="edit-stack"),
url(r"^del_stack/(?P<stackid>[0-9]+)$", views.del_stack, name="del-stack"),

View file

@ -242,35 +242,12 @@ def index_ap(request):
@login_required
@can_view_all(Stack, Building, Dormitory, SwitchBay)
def index_physical_grouping(request):
"""View used to display the list of stacks (display all switches)."""
stack_list = Stack.objects.prefetch_related(
"switch_set__interface_set__domain__extension"
)
building_list = Building.objects.all().select_related("dormitory")
dormitory_list = Dormitory.objects.all().prefetch_related("building_set")
@can_view_all(SwitchBay)
def index_switch_bay(request):
"""View used to display the list of switch bays."""
switch_bay_list = SwitchBay.objects.select_related(
"building__dormitory"
).prefetch_related("switch_set__interface_set__domain")
stack_list = SortTable.sort(
stack_list,
request.GET.get("col"),
request.GET.get("order"),
SortTable.TOPOLOGIE_INDEX_STACK,
)
building_list = SortTable.sort(
building_list,
request.GET.get("col"),
request.GET.get("order"),
SortTable.TOPOLOGIE_INDEX_BUILDING,
)
dormitory_list = SortTable.sort(
dormitory_list,
request.GET.get("col"),
request.GET.get("order"),
SortTable.TOPOLOGIE_INDEX_DORMITORY,
)
switch_bay_list = SortTable.sort(
switch_bay_list,
request.GET.get("col"),
@ -279,15 +256,64 @@ def index_physical_grouping(request):
)
return render(
request,
"topologie/index_physical_grouping.html",
"topologie/index_switch_bay.html",
{
"stack_list": stack_list,
"switch_bay_list": switch_bay_list,
"building_list": building_list,
"dormitory_list": dormitory_list,
},
)
@login_required
@can_view_all(Stack)
def index_stack(request):
"""View used to display the list of stacks (display all switches)."""
stack_list = Stack.objects.prefetch_related(
"switch_set__interface_set__domain__extension"
)
return render(
request,
"topologie/index_stack.html",
{
"stack_list": stack_list,
},
)
@login_required
@can_view_all(Building)
def index_building(request):
"""View used to display the list of buildings"""
building_list = Building.objects.all().select_related("dormitory")
building_list = SortTable.sort(
building_list,
request.GET.get("col"),
request.GET.get("order"),
SortTable.TOPOLOGIE_INDEX_BUILDING,
)
return render(
request,
"topologie/index_building.html",
{
"building_list": building_list,
},
)
@login_required
@can_view_all(Dormitory)
def index_dormitory(request):
"""View used to display the list of dormitories."""
dormitory_list = Dormitory.objects.all().prefetch_related("building_set")
dormitory_list = SortTable.sort(
dormitory_list,
request.GET.get("col"),
request.GET.get("order"),
SortTable.TOPOLOGIE_INDEX_DORMITORY,
)
return render(
request,
"topologie/index_dormitory.html",
{
"dormitory_list": dormitory_list,
},
)
@login_required
@can_view_all(ModelSwitch, ConstructorSwitch)
@ -440,7 +466,7 @@ def new_stack(request):
if stack.is_valid():
stack.save()
messages.success(request, _("The stack was created."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-stack"))
return form(
{"topoform": stack, "action_name": _("Add")}, "topologie/topo.html", request
)
@ -455,7 +481,7 @@ def edit_stack(request, stack, **_kwargs):
if stack.changed_data:
stack.save()
messages.success(request, _("The stack was edited."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-stack"))
return form(
{"topoform": stack, "action_name": _("Edit")}, "topologie/topo.html", request
)
@ -480,7 +506,7 @@ def del_stack(request, stack, **_kwargs):
% stack
),
)
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-stack"))
return form({"objet": stack}, "topologie/delete.html", request)
@ -847,7 +873,7 @@ def new_switch_bay(request):
if switch_bay.is_valid():
switch_bay.save()
messages.success(request, _("The switch bay was created."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-switch-bay"))
return form(
{"topoform": switch_bay, "action_name": _("Add")},
"topologie/topo.html",
@ -864,7 +890,7 @@ def edit_switch_bay(request, switch_bay, **_kwargs):
if switch_bay.changed_data:
switch_bay.save()
messages.success(request, _("The switch bay was edited."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-switch-bay"))
return form(
{"topoform": switch_bay, "action_name": _("Edit")},
"topologie/topo.html",
@ -891,7 +917,7 @@ def del_switch_bay(request, switch_bay, **_kwargs):
% switch_bay
),
)
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-switch-bay"))
return form(
{"objet": switch_bay, "objet_name": _("switch bay")},
"topologie/delete.html",
@ -907,7 +933,7 @@ def new_building(request):
if building.is_valid():
building.save()
messages.success(request, _("The building was created."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-building"))
return form(
{"topoform": building, "action_name": _("Add")},
"topologie/topo.html",
@ -924,7 +950,7 @@ def edit_building(request, building, **_kwargs):
if building.changed_data:
building.save()
messages.success(request, _("The building was edited."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-building"))
return form(
{"topoform": building, "action_name": _("Edit")}, "topologie/topo.html", request
)
@ -949,7 +975,7 @@ def del_building(request, building, **_kwargs):
% building
),
)
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-building"))
return form(
{"objet": building, "objet_name": _("building")},
"topologie/delete.html",
@ -965,7 +991,7 @@ def new_dormitory(request):
if dormitory.is_valid():
dormitory.save()
messages.success(request, _("The dormitory was created."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-dormitory"))
return form(
{"topoform": dormitory, "action_name": _("Add")},
"topologie/topo.html",
@ -982,7 +1008,7 @@ def edit_dormitory(request, dormitory, **_kwargs):
if dormitory.changed_data:
dormitory.save()
messages.success(request, _("The dormitory was edited."))
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-dormitory"))
return form(
{"topoform": dormitory, "action_name": _("Edit")},
"topologie/topo.html",
@ -1009,7 +1035,7 @@ def del_dormitory(request, dormitory, **_kwargs):
% dormitory
),
)
return redirect(reverse("topologie:index-physical-grouping"))
return redirect(reverse("topologie:index-dormitory"))
return form(
{"objet": dormitory, "objet_name": _("dormitory")},
"topologie/delete.html",

View file

@ -41,11 +41,14 @@ of each of the method.
from __future__ import unicode_literals
from os import walk, path
from django import forms
from django.forms import ModelForm, Form
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.password_validation import validate_password, password_validators_help_text_html
from django.core.validators import MinLengthValidator
from django.conf import settings
from django.utils import timezone
from django.utils.functional import lazy
from django.contrib.auth.models import Group, Permission
@ -1040,3 +1043,17 @@ class InitialRegisterForm(forms.Form):
if self.cleaned_data["register_machine"]:
if self.mac_address and self.nas_type:
self.user.autoregister_machine(self.mac_address, self.nas_type)
class ThemeForm(FormRevMixin, forms.Form):
"""Form to change the theme of a user.
"""
theme = forms.ChoiceField(widget=forms.Select())
def __init__(self, *args, **kwargs):
_, _ ,themes = next(walk(path.join(settings.STATIC_ROOT, "css/themes")))
if not themes:
themes = ["default.css"]
super(ThemeForm, self).__init__(*args, **kwargs)
self.fields['theme'].choices = [(theme, theme) for theme in themes]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-11-16 18:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0094_remove_user_profile_image'),
]
operations = [
migrations.AddField(
model_name='user',
name='theme',
field=models.CharField(default='default.css', max_length=255),
),
]

View file

@ -305,6 +305,7 @@ class User(
verbose_name=_("enable shortcuts on Re2o website"), default=True
)
email_change_date = models.DateTimeField(auto_now_add=True)
theme = models.CharField(max_length=255, default="default.css")
USERNAME_FIELD = "pseudo"
REQUIRED_FIELDS = ["surname", "email"]
@ -1963,6 +1964,14 @@ class User(
def __str__(self):
return self.pseudo
@property
def theme_name(self):
"""Return the theme without the extension
Returns:
str: name of theme
"""
return self.theme.split(".")[0]
class Adherent(User):
"""Base re2o Adherent model, inherit from User. Add other attributes.

View file

@ -25,11 +25,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load bootstrap3 %}
{% load i18n %}
{% load acl %}
{% block title %}{% trans "Users" %}{% endblock %}
{% block content %}
<h2>{% trans "Users" %}</h2>
{% can_create User %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:new-user' %}"><i class="fa fa-plus"></i> {% trans "Add a user" %}</a>
{% acl_end %}
{% include 'users/aff_users.html' with users_list=users_list %}
<br />
<br />

View file

@ -25,11 +25,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load bootstrap3 %}
{% load i18n %}
{% load acl %}
{% block title %}{% trans "Users" %}{% endblock %}
{% block content %}
<h2>{% trans "Clubs" %}</h2>
{% can_create Club %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:new-club' %}"><i class="fa fa-plus"></i> {% trans "Add a club" %}</a>
{% acl_end %}
{% include 'users/aff_clubs.html' with clubs_list=clubs_list %}
<br />
<br />

View file

@ -176,6 +176,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Edit the groups" %}
</a>
{% acl_end %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-theme' users.id %}">
<i class="fa fa-paint-brush"></i>
{% trans "Change theme" %}
</a>
{% history_button users text=True %}
</ul>
</div>
@ -345,6 +349,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<dt>{% trans "Shortcuts enabled" %}</dt>
<dd>{{ users.shortcuts_enabled | tick }}</dd>
</div>
<div class="col-md-6 col-xs-12">
<dt>{% trans "Theme" %}</dt>
<dd>{{ request.user.theme_name }}</dd>
</div>
</dl>
</div>
</div>

View file

@ -26,73 +26,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load i18n %}
{% block sidebar %}
{% if request.user.is_authenticated%}
{% can_create Club %}
<a class="list-group-item list-group-item-success" href="{% url 'users:new-club' %}">
<i class="fa fa-plus"></i>
{% trans "Create a club or organisation" %}
</a>
{% acl_end %}
{% can_create Adherent %}
<a class="list-group-item list-group-item-success" href="{% url 'users:new-user' %}">
<i class="fa fa-user-plus"></i>
{% trans "Create a user" %}
</a>
{% acl_end %}
{% endif %}
{% can_view_all Club %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-clubs' %}">
<i class="fa fa-list-ul"></i>
{% trans "Clubs and organisations" %}
</a>
{% acl_end %}
{% can_view_all Adherent %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index' %}">
<i class="fa fa-list-ul"></i>
{% trans "Users" %}
</a>
{% acl_end %}
{% can_view_all Ban %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-ban' %}">
<i class="fa fa-list-ul"></i>
{% trans "Bans" %}
</a>
{% acl_end %}
{% can_view_all Whitelist %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-white' %}">
<i class="fa fa-list-ul"></i>
{% trans "Whitelists" %}
</a>
{% acl_end %}
{% can_view_all School %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-school' %}">
<i class="fa fa-list-ul"></i>
{% trans "Schools" %}
</a>
{% acl_end %}
{% can_view_all ListShell %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-shell' %}">
<i class="fa fa-list-ul"></i>
{% trans "Shells" %}
</a>
{% acl_end %}
{% can_view_all ListRight %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-listright' %}">
<i class="fa fa-list-ul"></i>
{% trans "Groups of rights" %}
</a>
{% acl_end %}
{% can_view_all ServiceUser %}
<a class="list-group-item list-group-item-info" href="{% url 'users:index-serviceusers' %}">
<i class="fa fa-list-ul"></i>
{% trans "Service users" %}
</a>
{% acl_end %}
{% can_change User state %}
<a class="list-group-item list-group-item-danger" href="{% url 'users:mass-archive' %}">
<i class="fa fa-archive"></i>
{% trans "Massively archive" %}
</a>
{% acl_end %}
{% endblock %}

View file

@ -127,4 +127,5 @@ urlpatterns = [
url(r"^$", views.index, name="index"),
url(r"^index_clubs/$", views.index_clubs, name="index-clubs"),
url(r"^initial_register/$", views.initial_register, name="initial-register"),
url(r"^edit_theme/(?P<userid>[0-9]+)$", views.edit_theme, name="edit-theme"),
]

View file

@ -128,6 +128,7 @@ from .forms import (
ClubAdminandMembersForm,
GroupForm,
InitialRegisterForm,
ThemeForm
)
import os
@ -1593,3 +1594,27 @@ def initial_register(request):
request,
)
@login_required
@can_edit(User)
def edit_theme(request, user, userid):
"""View for editing base user informations.
Perform an acl check on user instance.
Parameters:
request (django request): Standard django request.
user: User instance to edit
Returns:
Django User form.
"""
theme_form = ThemeForm(request.POST or None, initial={'theme':user.theme})
if theme_form.is_valid():
user.theme = theme_form.cleaned_data["theme"]
user.save()
messages.success(request, _("The theme was edited."))
return redirect(reverse("users:profil", kwargs={"userid": str(userid)}))
return form(
{"userform": theme_form, "action_name": _("Edit")}, "users/user.html", request,
)