Compare commits

..
4 Commits
Author SHA1 Message Date
imperosol 95865cfa6e add translations 2026-09-14 11:48:39 +02:00
imperosol b2317c8329 style: improve ue comments appearance 2026-09-14 11:48:01 +02:00
imperosol de80f1b6f5 style: improve ue comment form appearance 2026-09-14 11:23:03 +02:00
imperosol e2f32d1fe5 style: improve ue detail infos appearance 2026-09-14 11:01:17 +02:00
26 changed files with 547 additions and 752 deletions
@@ -18,7 +18,7 @@ class Migration(migrations.Migration):
"Groups that are automatically given or removed " "Groups that are automatically given or removed "
"to user receiving or losing this club role" "to user receiving or losing this club role"
), ),
related_name="linked_roles", related_name="club_roles",
to="core.group", to="core.group",
verbose_name="Linked groups", verbose_name="Linked groups",
), ),
+5 -12
View File
@@ -28,7 +28,6 @@ from typing import ClassVar, NamedTuple
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.files.base import ContentFile
from django.core.management import call_command from django.core.management import call_command
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.db import connection from django.db import connection
@@ -121,21 +120,15 @@ class Command(BaseCommand):
) )
self.profiles_root = SithFile.objects.create(name="profiles", owner=root) self.profiles_root = SithFile.objects.create(name="profiles", owner=root)
home_root = SithFile.objects.create(name="users", owner=root) home_root = SithFile.objects.create(name="users", owner=root)
# Page needed for club creation
p = Page(name=settings.SITH_CLUB_ROOT_PAGE)
p.save(force_lock=True)
club_root = SithFile.objects.create(name="clubs", owner=root) club_root = SithFile.objects.create(name="clubs", owner=root)
sas = SithFile.objects.create( sas = SithFile.objects.create(
name="SAS", owner=root, id=settings.SITH_SAS_ROOT_DIR_ID name="SAS", owner=root, id=settings.SITH_SAS_ROOT_DIR_ID
) )
SithFile.objects.create(
name="CGU",
is_folder=False,
file=ContentFile(
content="Conditions générales d'utilisation", name="cgu.txt"
),
owner=root,
)
# Page needed for club creation
p = Page(name=settings.SITH_CLUB_ROOT_PAGE)
p.save(force_lock=True)
clubs = self._create_clubs() clubs = self._create_clubs()
self.reset_index("club") self.reset_index("club")
@@ -1,15 +0,0 @@
# Generated by Django 5.2.17 on 2026-09-15 11:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("core", "0050_alter_sithfile_moderator")]
operations = [
migrations.AddField(
model_name="user",
name="cgu_approved",
field=models.BooleanField(default=False, verbose_name="EULA approved"),
),
]
-1
View File
@@ -291,7 +291,6 @@ class User(AbstractUser):
), ),
blank=True, blank=True,
) )
cgu_approved = models.BooleanField(_("EULA approved"), default=False)
godfathers = models.ManyToManyField("User", related_name="godchildren", blank=True) godfathers = models.ManyToManyField("User", related_name="godchildren", blank=True)
objects = CustomUserManager() objects = CustomUserManager()
+1
View File
@@ -42,6 +42,7 @@ details.accordion>.accordion-content {
background: #ffffff; background: #ffffff;
color: #333333; color: #333333;
padding: 1em 2.2em; padding: 1em 2.2em;
margin-top: 0;
border: 1px solid #dddddd; border: 1px solid #dddddd;
border-bottom-right-radius: 3px; border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px; border-bottom-left-radius: 3px;
+44 -6
View File
@@ -49,29 +49,67 @@ body {
max-width: 500px; max-width: 500px;
margin-top: 20px; margin-top: 20px;
input[type="submit"] { >p,
>div {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%; width: 100%;
max-width: 300px;
margin: 0; margin: 0;
>label {
width: 100%;
@media (min-width: 500px) {
width: 300px;
}
}
} }
.errorlist { >input,
>p>input,
>div>input {
box-sizing: border-box;
width: 100%;
max-width: 500px;
@media (min-width: 500px) {
max-width: 300px;
}
}
>.errorlist {
color: red; color: red;
text-align: center; text-align: center;
margin: 10px 0 0 0; margin: 10px 0 0 0;
list-style-type: none; list-style-type: none;
} }
div, fieldset { >.required>.helptext {
max-width: 300px; text-align: center;
font-style: italic;
} }
.captcha {
>.required:last-of-type {
box-sizing: border-box; box-sizing: border-box;
max-width: 300px;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
>label {
width: 100%;
}
>img { >img {
width: 70px; width: 70px;
object-fit: contain; object-fit: contain;
} }
>input {
width: 200px;
}
} }
} }
} }
+5 -4
View File
@@ -50,12 +50,13 @@
<input type="hidden" name="next" value="{{ next }}"> <input type="hidden" name="next" value="{{ next }}">
<input type="submit" value="{% trans %}Login{% endtrans %}"> <input type="submit" value="{% trans %}Login{% endtrans %}">
<div>
{# Assumes you setup the password_reset view in your URLconf #}
<p>
<a href="{{ url('core:password_reset') }}">{% trans %}Lost password?{% endtrans %}</a> <a href="{{ url('core:password_reset') }}">{% trans %}Lost password?{% endtrans %}</a>
</div> &nbsp;&nbsp;
<div>
<a href="{{ url('core:register') }}">{% trans %}Create account{% endtrans %}</a> <a href="{{ url('core:register') }}">{% trans %}Create account{% endtrans %}</a>
</div> </p>
</form> </form>
{% endblock %} {% endblock %}
+2 -12
View File
@@ -18,17 +18,7 @@
<form action="{{ url('core:register') }}" method="post"> <form action="{{ url('core:register') }}" method="post">
{% csrf_token %} {% csrf_token %}
{% render_honeypot_field %} {% render_honeypot_field %}
{% for field in form %} {{ form.as_p() }}
{% if field.name not in ["cgu_approved", "captcha"] %} <input type="submit" value="{% trans %}Register{% endtrans %}" />
<div>{{ field.as_field_group() }}</div>
{% endif %}
{% endfor %}
<div class="captcha">{{ form.captcha.as_field_group() }}</div>
<fieldset>
{{ form.cgu_approved.errors }}
{{ form.cgu_approved }}
{{ form.cgu_approved.label_tag() }}
</fieldset>
<input type="submit" class="btn btn-blue" value="{% trans %}Register{% endtrans %}" />
</form> </form>
{% endblock %} {% endblock %}
-2
View File
@@ -55,7 +55,6 @@ class TestUserRegistration:
"password2": "plop", "password2": "plop",
"captcha_0": "dummy-value", "captcha_0": "dummy-value",
"captcha_1": "PASSED", "captcha_1": "PASSED",
"cgu_approved": True,
} }
@pytest.fixture() @pytest.fixture()
@@ -93,7 +92,6 @@ class TestUserRegistration:
({"first_name": ""}, "Ce champ est obligatoire."), ({"first_name": ""}, "Ce champ est obligatoire."),
({"last_name": ""}, "Ce champ est obligatoire."), ({"last_name": ""}, "Ce champ est obligatoire."),
({"captcha_1": "WRONG_CAPTCHA"}, "CAPTCHA invalide"), ({"captcha_1": "WRONG_CAPTCHA"}, "CAPTCHA invalide"),
({"cgu_approved": ""}, "Ce champ est obligatoire."),
], ],
) )
def test_register_user_form_fail( def test_register_user_form_fail(
+1 -19
View File
@@ -42,8 +42,6 @@ from django.forms import (
TextInput, TextInput,
Widget, Widget,
) )
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from phonenumber_field.widgets import RegionalPhoneNumberWidget from phonenumber_field.widgets import RegionalPhoneNumberWidget
@@ -148,25 +146,9 @@ class RegisteringForm(UserCreationForm):
class Meta: class Meta:
model = User model = User
fields = ("first_name", "last_name", "email", "cgu_approved") fields = ("first_name", "last_name", "email")
field_classes = {"email": AntiSpamEmailField} field_classes = {"email": AntiSpamEmailField}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["cgu_approved"].required = True
self.fields["cgu_approved"].label_suffix = ""
self.fields["cgu_approved"].label = mark_safe(
_(
"I have read and I approve the "
'<a href="%(url)s" target="_blank">End User License Agreement</a>'
)
% {
"url": reverse(
"core:download", kwargs={"file_id": settings.SITH_CGU_FILE_ID}
)
}
)
class UserProfileForm(forms.ModelForm): class UserProfileForm(forms.ModelForm):
"""Form handling the user profile, managing the files""" """Form handling the user profile, managing the files"""
@@ -11,7 +11,7 @@ class Migration(migrations.Migration):
model_name="permanency", model_name="permanency",
name="end", name="end",
field=models.DateTimeField( field=models.DateTimeField(
db_index=True, verbose_name="end date", null=True, blank=True db_index=True, verbose_name="end date", null=True
), ),
) )
] ]
+3 -1
View File
@@ -6,7 +6,9 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [("counter", "0018_producttype_priority")] dependencies = [
("counter", "0018_producttype_priority"),
]
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
@@ -6,7 +6,9 @@ import counter.fields
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [("counter", "0019_billinginfo")] dependencies = [
("counter", "0019_billinginfo"),
]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
+82 -84
View File
@@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-15 23:49+0200\n" "POT-Creation-Date: 2026-09-14 11:48+0200\n"
"PO-Revision-Date: 2016-07-18\n" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n" "Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@@ -736,8 +736,9 @@ msgstr "Méthode de paiement"
#: counter/templates/counter/fragments/create_student_card.jinja #: counter/templates/counter/fragments/create_student_card.jinja
#: counter/templates/counter/last_ops.jinja #: counter/templates/counter/last_ops.jinja
#: election/templates/election/election_detail.jinja #: election/templates/election/election_detail.jinja
#: forum/templates/forum/macros.jinja pedagogy/templates/pedagogy/guide.jinja #: forum/templates/forum/macros.jinja
#: pedagogy/templates/pedagogy/ue_detail.jinja sas/templates/sas/album.jinja #: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/guide.jinja sas/templates/sas/album.jinja
#: sas/templates/sas/moderation.jinja sas/templates/sas/picture.jinja #: sas/templates/sas/moderation.jinja sas/templates/sas/picture.jinja
#: trombi/templates/trombi/detail.jinja #: trombi/templates/trombi/detail.jinja
#: trombi/templates/trombi/edit_profile.jinja #: trombi/templates/trombi/edit_profile.jinja
@@ -931,8 +932,9 @@ msgstr "Outils"
#: counter/templates/counter/cash_summary_list.jinja #: counter/templates/counter/cash_summary_list.jinja
#: counter/templates/counter/counter_list.jinja #: counter/templates/counter/counter_list.jinja
#: election/templates/election/election_detail.jinja #: election/templates/election/election_detail.jinja
#: forum/templates/forum/macros.jinja pedagogy/templates/pedagogy/guide.jinja #: forum/templates/forum/macros.jinja
#: pedagogy/templates/pedagogy/ue_detail.jinja sas/templates/sas/album.jinja #: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/guide.jinja sas/templates/sas/album.jinja
#: trombi/templates/trombi/detail.jinja #: trombi/templates/trombi/detail.jinja
#: trombi/templates/trombi/edit_profile.jinja #: trombi/templates/trombi/edit_profile.jinja
msgid "Edit" msgid "Edit"
@@ -1188,8 +1190,9 @@ msgstr "Actions"
#: com/templates/com/mailing_admin.jinja com/templates/com/poster_list.jinja #: com/templates/com/mailing_admin.jinja com/templates/com/poster_list.jinja
#: core/templates/core/file_detail.jinja #: core/templates/core/file_detail.jinja
#: core/templates/core/file_moderation.jinja sas/templates/sas/moderation.jinja #: core/templates/core/file_moderation.jinja
#: sas/templates/sas/picture.jinja #: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: sas/templates/sas/moderation.jinja sas/templates/sas/picture.jinja
msgid "Moderate" msgid "Moderate"
msgstr "Modérer" msgstr "Modérer"
@@ -1491,7 +1494,6 @@ msgstr "Descendre"
#: com/templates/com/weekmail_preview.jinja #: com/templates/com/weekmail_preview.jinja
#: core/templates/core/user_account_detail.jinja #: core/templates/core/user_account_detail.jinja
#: pedagogy/templates/pedagogy/ue_detail.jinja
#: trombi/templates/trombi/comment_moderation.jinja #: trombi/templates/trombi/comment_moderation.jinja
#: trombi/templates/trombi/export.jinja #: trombi/templates/trombi/export.jinja
msgid "Back" msgid "Back"
@@ -1835,10 +1837,6 @@ msgstr ""
"Même si ce profil est caché, les utilisateurs sur cette liste pourront " "Même si ce profil est caché, les utilisateurs sur cette liste pourront "
"toujours le voir." "toujours le voir."
#: core/models.py
msgid "EULA approved"
msgstr "CGU approuvées"
#: core/models.py #: core/models.py
msgid "A user with that username already exists" msgid "A user with that username already exists"
msgstr "Un utilisateur de ce nom d'utilisateur existe déjà" msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
@@ -1846,7 +1844,9 @@ msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
#: core/models.py core/templates/core/macros.jinja #: core/models.py core/templates/core/macros.jinja
#: core/templates/core/user_detail.jinja core/templates/core/user_edit.jinja #: core/templates/core/user_detail.jinja core/templates/core/user_edit.jinja
#: election/templates/election/election_detail.jinja #: election/templates/election/election_detail.jinja
#: forum/templates/forum/macros.jinja trombi/templates/trombi/user_tools.jinja #: forum/templates/forum/macros.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: trombi/templates/trombi/user_tools.jinja
msgid "Profile" msgid "Profile"
msgstr "Profil" msgstr "Profil"
@@ -2237,6 +2237,7 @@ msgstr "Confirmation"
#: core/templates/core/file_delete_confirm.jinja #: core/templates/core/file_delete_confirm.jinja
#: counter/templates/counter/counter_click.jinja #: counter/templates/counter/counter_click.jinja
#: counter/templates/counter/fragments/delete_student_card.jinja #: counter/templates/counter/fragments/delete_student_card.jinja
#: pedagogy/templates/pedagogy/fragments/comment_report.jinja
#: sas/templates/sas/ask_picture_removal.jinja #: sas/templates/sas/ask_picture_removal.jinja
msgid "Cancel" msgid "Cancel"
msgstr "Annuler" msgstr "Annuler"
@@ -3141,15 +3142,6 @@ msgstr "Assurez-vous que cet horodatage est dans le futur"
msgid "Username, email, or account number" msgid "Username, email, or account number"
msgstr "Nom d'utilisateur, email, ou numéro de compte AE" msgstr "Nom d'utilisateur, email, ou numéro de compte AE"
#: core/views/forms.py
#, python-format
msgid ""
"I have read and I approve the <a href=\"%(url)s\" target=\"_blank\">End User "
"License Agreement</a>"
msgstr ""
"J'ai lu et j'approuve les <a href=\"%(url)s\" target=\"_blank\">Conditions "
"Générales d'utilisation</a>"
#: core/views/forms.py #: core/views/forms.py
msgid "" msgid ""
"Profile: you need to be visible on the picture, in order to be recognized " "Profile: you need to be visible on the picture, in order to be recognized "
@@ -3791,7 +3783,6 @@ msgid "Emptied"
msgstr "Coffre vidé" msgstr "Coffre vidé"
#: counter/templates/counter/cash_summary_list.jinja counter/views/cash.py #: counter/templates/counter/cash_summary_list.jinja counter/views/cash.py
#: pedagogy/templates/pedagogy/fragments/ue_comment_form.jinja
#: pedagogy/templates/pedagogy/moderation.jinja #: pedagogy/templates/pedagogy/moderation.jinja
#: trombi/templates/trombi/comment.jinja #: trombi/templates/trombi/comment.jinja
#: trombi/templates/trombi/user_tools.jinja #: trombi/templates/trombi/user_tools.jinja
@@ -5122,6 +5113,62 @@ msgstr "signaler"
msgid "reporter" msgid "reporter"
msgstr "signalant" msgstr "signalant"
#: pedagogy/templates/pedagogy/fragments/comment_report.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
msgid "Report"
msgstr "Signaler"
#: pedagogy/templates/pedagogy/fragments/ue_comment_form.jinja
msgid "Leave comment"
msgstr "Laisser un commentaire"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: trombi/templates/trombi/export.jinja
msgid "Comments"
msgstr "Commentaires"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
msgid "This comment has been reported"
msgstr "Ce commentaire a été signalé"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
msgid "It will be hidden until moderated."
msgstr "Il sera caché tant qu'il ne sera pas modéré."
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/grade.jinja
msgid "Global grade"
msgstr "Note globale"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/grade.jinja
msgid "Utility"
msgstr "Utilité"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/grade.jinja
msgid "Interest"
msgstr "Intérêt"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/grade.jinja
msgid "Teaching"
msgstr "Enseignement"
#: pedagogy/templates/pedagogy/fragments/ue_detail/comments.jinja
#: pedagogy/templates/pedagogy/fragments/ue_detail/grade.jinja
msgid "Workload"
msgstr "Charge de travail"
#: pedagogy/templates/pedagogy/fragments/ue_detail/ue_detail.jinja
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid ""
"You already posted a comment on this UE. If you want to comment again, "
"please modify or delete your previous comment."
msgstr ""
"Vous avez déjà commenté cette UE. Si vous voulez de nouveau commenter, "
"veuillez modifier ou supprimer votre commentaire précédent."
#: pedagogy/templates/pedagogy/guide.jinja #: pedagogy/templates/pedagogy/guide.jinja
msgid "A guide of courses available at UTBM." msgid "A guide of courses available at UTBM."
msgstr "Un guide de tous les cours disponibles à l'UTBM." msgstr "Un guide de tous les cours disponibles à l'UTBM."
@@ -5130,6 +5177,10 @@ msgstr "Un guide de tous les cours disponibles à l'UTBM."
msgid "Search UE" msgid "Search UE"
msgstr "Recherche d'UE" msgstr "Recherche d'UE"
#: pedagogy/templates/pedagogy/guide.jinja
msgid "Hide closed UEs"
msgstr "Cacher les UEs fermées"
#: pedagogy/templates/pedagogy/guide.jinja #: pedagogy/templates/pedagogy/guide.jinja
#, python-format #, python-format
msgid "%(display_name)s" msgid "%(display_name)s"
@@ -5183,44 +5234,20 @@ msgid "UE Details"
msgstr "Détails d'UE" msgstr "Détails d'UE"
#: pedagogy/templates/pedagogy/ue_detail.jinja #: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "CM: " msgid "Category"
msgstr "CM : " msgstr "Catégorie"
#: pedagogy/templates/pedagogy/ue_detail.jinja #: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "TD: " msgid "Credits"
msgstr "TD : " msgstr "Crédits"
#: pedagogy/templates/pedagogy/ue_detail.jinja #: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "TP: " msgid "Availability"
msgstr "TP : " msgstr "Disponibilité"
#: pedagogy/templates/pedagogy/ue_detail.jinja #: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "TE: " msgid "Manager"
msgstr "TE : " msgstr "Responsable"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "THE: "
msgstr "THE : "
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Global grade"
msgstr "Note globale"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Utility"
msgstr "Utilité"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Interest"
msgstr "Intérêt"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Teaching"
msgstr "Enseignement"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Work load"
msgstr "Charge de travail"
#: pedagogy/templates/pedagogy/ue_detail.jinja #: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Objectives" msgid "Objectives"
@@ -5238,35 +5265,6 @@ msgstr "Compétences acquises"
msgid "Key concepts" msgid "Key concepts"
msgstr "Concepts clefs" msgstr "Concepts clefs"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "UE manager: "
msgstr "Gestionnaire d'UE : "
#: pedagogy/templates/pedagogy/ue_detail.jinja pedagogy/tests/tests.py
msgid ""
"You already posted a comment on this UE. If you want to comment again, "
"please modify or delete your previous comment."
msgstr ""
"Vous avez déjà commenté cette UE. Si vous voulez de nouveau commenter, "
"veuillez modifier ou supprimer votre commentaire précédent."
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Leave comment"
msgstr "Laisser un commentaire"
#: pedagogy/templates/pedagogy/ue_detail.jinja
#: trombi/templates/trombi/export.jinja
msgid "Comments"
msgstr "Commentaires"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "This comment has been reported"
msgstr "Ce commentaire a été signalé"
#: pedagogy/templates/pedagogy/ue_detail.jinja
msgid "Report this comment"
msgstr "Signaler ce commentaire"
#: pedagogy/templates/pedagogy/ue_edit.jinja #: pedagogy/templates/pedagogy/ue_edit.jinja
msgid "Edit UE" msgid "Edit UE"
msgstr "Éditer l'UE" msgstr "Éditer l'UE"
+110 -346
View File
@@ -1,52 +1,22 @@
@import "core/static/core/devices"; @import "core/static/core/devices";
@import "core/static/core/colors"; @import "core/static/core/colors";
$pedagogy-blue: #1bb9ea;
$pedagogy-orange: #ea7900; $pedagogy-orange: #ea7900;
$pedagogy-hover-blue: #0e97ce;
$pedagogy-light-blue: #caf0ff;
$pedagogy-white-text: #f0f0f0; $pedagogy-white-text: #f0f0f0;
.pedagogy { .pedagogy {
&.star-not-checked { .star-not-checked {
color: #f7f7f7; color: lightgray;
margin-bottom: 0; margin-bottom: 0;
margin-top: 0; margin-top: 0;
} }
&.star-checked { .star-checked {
color: $pedagogy-orange; color: $pedagogy-orange;
margin-bottom: 0; margin-bottom: 0;
margin-top: 0; margin-top: 0;
} }
&.grade-without-star {
display: none;
}
@media screen and (max-width: $large-devices) {
&.star-not-checked {
margin-left: 5px;
margin-right: 5px;
}
&.star-checked {
margin-left: 5px;
margin-right: 5px;
}
}
@media screen and (max-width: $small-devices) {
&.grade-without-star {
display: block;
}
&.grade-with-star {
display: none;
}
}
#ue-list { #ue-list {
font-size: 1.1em; font-size: 1.1em;
@@ -64,12 +34,10 @@ $pedagogy-white-text: #f0f0f0;
} }
#search_form { #search_form {
.radio-guide fieldset { .radio-guide fieldset {
input[type="checkbox"] { input[type="checkbox"] {
display: none; display: none;
} }
margin-top: 10px; margin-top: 10px;
margin-bottom: 0; margin-bottom: 0;
color: white; color: white;
@@ -85,80 +53,79 @@ $pedagogy-white-text: #f0f0f0;
} }
} }
#ue_detail { &#ue_detail {
color: #062f38; .ue-infos {
display: flex;
.ue-quick-info-container { gap: 2em;
flex-direction: row;
@media screen and (max-width: 700px) {
flex-direction: column;
}
}
.infos-column {
display: flex;
flex-direction: column;
gap: 1em;
min-width: 300px;
}
.info-container {
// Darken the background color just enough to make this part
// stand out a little, while not being too perceptible
background: darken($white-color, 1%);
display: grid; display: grid;
grid-template-columns: 20% 20% 20% 20% auto; grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto; border-radius: 5px;
grid-template-areas: padding: .75rem 1rem ;
"hours-cm hours-td hours-tp hours-te hours-the" grid-gap: .5rem;
"department credit-type semester . ."; @include shadow;
.info-container-item {
display: grid;
grid-column: span 2;
grid-template-rows: subgrid;
grid-template-columns: subgrid;
grid-column-gap: 1rem;
div {
display: flex;
align-items: center;
} }
.department { :first-child {
grid-area: department; justify-content: right;
text-align: right;
}
} }
.credit-type { hr {
grid-area: credit-type; grid-column: span 2;
} width: 50%;
margin: auto;
.semester {
grid-area: semester;
}
.hours-cm {
grid-area: hours-cm;
}
.hours-td {
grid-area: hours-td;
}
.hours-tp {
grid-area: hours-tp;
}
.hours-te {
grid-area: hours-te;
}
.hours-the {
grid-area: hours-the;
}
.leave-comment-not-allowed {
p {
text-align: center;
color: red;
} }
} }
.leave-comment { .leave-comment {
.leave-comment-grid-container { .comment-form-content {
display: grid; display: flex;
grid-template-columns: 270px auto; gap: 2em;
grid-template-rows: 100%;
grid-template-areas: "stars comment";
@media screen and (max-width: $large-devices) { @media screen and (max-width: $large-devices) {
grid-template-columns: 100%; gap: 1em;
grid-template-rows: auto auto; flex-direction: column;
grid-template-areas:
"stars"
"comment";
} }
} }
.form-stars { .form-stars {
grid-area: stars; flex: 0;
min-width: 250px;
display: flex;
align-content: flex-start;
justify-content: center;
flex-wrap: wrap;
gap: 1rem 2em;
height: unset;
} }
.form-comment { .form-comment {
grid-area: comment; flex: 2;
} }
.ui-accordion-header-icon { .ui-accordion-header-icon {
@@ -166,45 +133,18 @@ $pedagogy-white-text: #f0f0f0;
margin-right: 10px; margin-right: 10px;
} }
.input-stars { input[type="submit"] {
margin-top: 20px; display: block;
} margin-left: auto;
} }
.ue-details-container { summary {
display: grid; background: $pedagogy-orange;
grid-template-columns: 150px 130px auto;
grid-template-rows: 156px 1fr;
grid-template-areas:
"grade grade-stars ue-infos"
". . ue-infos";
@media screen and (max-width: $large-devices) {
grid-template-columns: 50% 50%;
grid-template-rows: auto auto;
grid-template-areas:
"grade grade-stars"
"ue-infos ue-infos";
}
}
.grade {
grid-area: grade;
color: $pedagogy-white-text; color: $pedagogy-white-text;
background-color: $pedagogy-blue; @media screen and (min-width: $large-devices) {
padding-right: 10px; clip-path: polygon(0 0%, 0 100%, 30% 100%, 33% 0);
>p {
text-align: right;
font-weight: bold;
} }
} }
.grade-stars {
grid-area: grade-stars;
color: $pedagogy-white-text;
background-color: $pedagogy-blue;
font-weight: bold;
} }
.ue-infos { .ue-infos {
@@ -212,236 +152,60 @@ $pedagogy-white-text: #f0f0f0;
padding-left: 10px; padding-left: 10px;
} }
.comment-container {
display: grid;
grid-template-columns: 300px auto;
grid-template-rows: auto auto auto;
grid-template-areas:
"grade-block comment"
"grade-block info"
"comment-end-bar comment-end-bar";
margin-bottom: 30px;
margin-top: 10px;
@media screen and (max-width: $large-devices) {
grid-template-columns: auto;
grid-template-rows: auto auto auto auto;
grid-template-areas:
"grade-block"
"comment"
"info"
"comment-end-bar";
}
.grade-block {
grid-area: grade-block;
width: 300px;
display: grid;
grid-template-columns: 150px 150px;
grid-template-rows: 156px auto;
grid-template-areas:
"grade-type grade-stars"
"grade-extension grade-extension";
grid-gap: 15px;
clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 30px, 270px 0);
align-items: start;
background-color: $pedagogy-blue;
@media screen and (max-width: $large-devices) {
grid-template-columns: 50% auto;
grid-template-rows: auto;
grid-template-areas: "grade-type grade-stars";
width: auto;
clip-path: none;
align-content: space-evenly;
align-items: end;
}
.grade-extension {
grid-area: grade-extension;
background-color: $pedagogy-blue;
}
.grade-type {
grid-area: grade-type;
>p {
color: $pedagogy-white-text;
font-weight: bold;
text-align: right;
}
}
.grade-stars {
grid-area: grade-stars;
}
}
.comment { .comment {
grid-area: comment; padding: 15px;
margin: 20px;
display: flex;
flex-direction: column;
gap: 10px;
background: $primary-neutral-light-color;
border-radius: 5px;
border: 1px darken($secondary-neutral-light-color, 10%) solid;
display: grid; &.reported {
grid-template-columns: auto; border: #fc8181 1px solid;
grid-template-rows: auto auto;
grid-template-areas:
"anchor"
"markdown";
@media screen and (max-width: $large-devices) {
border-left: solid;
border-right: solid;
border-color: $pedagogy-blue;
} }
.anchor { .comment-header {
grid-area: anchor; display: flex;
text-align: right; gap: 20px;
margin-right: 15px;
img {
width: 50px;
height: 50px;
border-radius: 50%;
} }
.markdown { .comment-metadata {
grid-area: markdown; display: flex;
flex-direction: column;
justify-content: center;
}
min-height: 139px; .comment-options {
margin-top: 0; flex: 2;
margin-right: 0; display: flex;
padding: 10px; justify-content: right;
gap: 15px;
}
}
.comment-stars {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
gap: 1em 2em;
padding: 1.5em;
border-top: 0.0625rem grey dotted;
border-bottom: 0.0625rem grey dotted;
}
.comment-content {
text-align: justify; text-align: justify;
overflow: auto; padding: .5em 20px 1em;
}
}
.info {
grid-area: info;
padding-bottom: 10px;
@media screen and (max-width: $large-devices) {
border-left: solid;
border-right: solid;
border-color: $pedagogy-blue;
}
.status-reported {
color: red;
float: left;
padding-left: 10px;
}
.action {
float: right;
margin-top: 0;
}
}
.comment-end-bar {
grid-area: comment-end-bar;
display: grid;
grid-template-columns: 33% auto auto;
grid-template-rows: 2.5em;
grid-template-areas: "author date report";
background-color: $pedagogy-blue;
margin-top: -1px;
@media screen and (max-width: $large-devices) {
grid-template-columns: auto;
grid-template-rows: auto auto auto;
grid-template-areas:
"report"
"date"
"author";
margin-top: 0;
text-align: center;
}
.author {
grid-area: author;
padding-top: 6px;
padding-left: 20px;
background-color: $pedagogy-orange;
clip-path: polygon(0 10px, 0 100%, 350px 200%, 300px 10px);
@media screen and (max-width: $large-devices) {
clip-path: none;
padding: 0;
padding-bottom: 7px;
}
a {
color: $pedagogy-white-text;
font-weight: bold;
}
a:hover {
color: $pedagogy-hover-blue;
}
}
.date {
grid-area: date;
color: $pedagogy-white-text;
@media screen and (max-width: $large-devices) {
padding-bottom: 7px;
}
}
.report {
grid-area: report;
justify-self: right;
padding-right: 30px;
padding-left: 30px;
a {
color: $pedagogy-white-text;
cursor: pointer;
}
a:hover {
color: $pedagogy-hover-blue;
}
@media screen and (max-width: $large-devices) {
text-align: center;
justify-self: inherit;
padding-bottom: 7px;
background-color: $white-color;
border-left: solid;
border-right: solid;
border-color: $pedagogy-blue;
a {
color: $black-color;
} }
} }
} }
}
}
}
}
details.accordion summary {
background: $pedagogy-orange !important;
color: $pedagogy-white-text !important;
clip-path: polygon(0 0%, 0 100%, 30% 100%, 33% 0);
@media screen and (max-width: $large-devices) {
clip-path: none;
}
}
details.accordion>.accordion-content {
background-color: $white-color;
border-color: $pedagogy-orange;
border-right: none;
} }
.buttons { .buttons {
@@ -5,50 +5,45 @@
<div class="accordion-content"> <div class="accordion-content">
{% endif %} {% endif %}
<form <form
hx-post="{{ action }}" class="accordion-content"
hx-target="closest .leave-comment" action="{{ url('pedagogy:ue_detail', ue_id=object.id) }}"
hx-swap="outerHTML" method="post"
hx-disabled-elt="find input[type='submit']" enctype="multipart/form-data"
> >
{% csrf_token %} {% csrf_token %}
<div class="leave-comment-grid-container">
<div class="form-stars">
{{ form.non_field_errors() }} {{ form.non_field_errors() }}
{{ form.author.errors }} {{ form.author.errors }}
{{ form.ue.errors }} {{ form.ue.errors }}
{{ form.author }} {{ form.author }}
{{ form.ue }} {{ form.ue }}
<div class="comment-form-content">
<div class="input-stars"> <div class="form-stars">
<label for="{{ form.grade_global.id_for_label }}">{{ form.grade_global.label }} :</label> <fieldset>
<legend>{{ form.grade_global.label }} :</legend>
{{ form.grade_global.errors }} {{ form.grade_global.errors }}
{{ form.grade_global }} {{ form.grade_global }}
</div> </fieldset>
<fieldset>
<div class="input-stars"> <legend>{{ form.grade_utility.label }} :</legend>
<label for="{{ form.grade_utility.id_for_label }}">{{ form.grade_utility.label }} :</label>
{{ form.grade_utility.errors }} {{ form.grade_utility.errors }}
{{ form.grade_utility }} {{ form.grade_utility }}
</div> </fieldset>
<fieldset>
<div class="input-stars"> <legend>{{ form.grade_interest.label }} :</legend>
<label for="{{ form.grade_interest.id_for_label }}">{{ form.grade_interest.label }} :</label>
{{ form.grade_interest.errors }} {{ form.grade_interest.errors }}
{{ form.grade_interest }} {{ form.grade_interest }}
</div> </fieldset>
<fieldset>
<div class="input-stars"> <legend>{{ form.grade_teaching.label }} :</legend>
<label for="{{ form.grade_teaching.id_for_label }}">{{ form.grade_teaching.label }} :</label>
{{ form.grade_teaching.errors }} {{ form.grade_teaching.errors }}
{{ form.grade_teaching }} {{ form.grade_teaching }}
</div> </fieldset>
<fieldset>
<div class="input-stars"> <legend>{{ form.grade_work_load.label }} :</legend>
<label for="{{ form.grade_work_load.id_for_label }}">{{ form.grade_work_load.label }} :</label>
{{ form.grade_work_load.errors }} {{ form.grade_work_load.errors }}
{{ form.grade_work_load }} {{ form.grade_work_load }}
</div> </fieldset>
</div> </div>
<div class="form-comment"> <div class="form-comment">
<label for="{{ form.comment.id_for_label }}">{{ form.comment.label }} :</label> <label for="{{ form.comment.id_for_label }}">{{ form.comment.label }} :</label>
@@ -56,9 +51,7 @@
{{ form.comment }} {{ form.comment }}
</div> </div>
</div> </div>
<div class="buttons"> <p><input type="submit" class="btn btn-blue"/></p>
<input type="submit" value="{% trans %}Comment{% endtrans %}" />
</div>
</form> </form>
{% if form.is_creation %} {% if form.is_creation %}
@@ -0,0 +1,129 @@
{% from "pedagogy/macros.jinja" import display_star %}
{% from "core/macros.jinja" import user_profile_link %}
{% if comments %}
<h2>{% trans %}Comments{% endtrans %}</h2>
<br>
{% endif %}
<section>
{%- for comment in comments -%}
<article
id="comment-{{ comment.id }}"
class="comment {% if comment.is_reported %}reported{% endif %}"
>
{% if comment.is_reported %}
<div class="alert alert-red">
<div class="alert-main">
<h5 class="alert-title margin-bottom">
{% trans %}This comment has been reported{% endtrans %}
</h5>
<p>{% trans %}It will be hidden until moderated.{% endtrans %}</p>
{% if user.has_perm("pedagogy.view_uecommentreport") %}
{% for report in comment.reports.all() %}
<div class="markdown margin-bottom">
<blockquote>
<em>{{ report.reporter.get_display_name() }}</em>
{{ report.reason|markdown }}
</blockquote>
</div>
{% endfor %}
{% endif %}
</div>
{% if user.has_perm("pedagogy.delete_uecomment") %}
<div class="alert-aside">
<a
href="{{ url("pedagogy:comment_delete", comment_id=comment.id) }}"
class="btn btn-red"
>
<i class="fa fa-trash"></i>{% trans %}Delete{% endtrans %}
</a>
<a href="{{ url("pedagogy:moderation") }}" class="btn btn-green">
<i class="fa fa-check"></i>{% trans %}Moderate{% endtrans %}
</a>
</div>
{% endif %}
</div>
{% endif %}
<div class="comment-header">
<img
{% if comment.author.avatar_pict %}
src="{{ comment.author.avatar_pict.get_download_url() }}"
{% elif comment.author.profile_pict %}
src="{{ comment.author.profile_pict.get_download_url() }}"
{% else %}
src="{{ static("core/img/unknown.jpg") }}"
{% endif %}
alt="{% trans %}Profile{% endtrans %}"
/>
<div class="comment-metadata">
<a href="{{ comment.author.get_absolute_url() }}">
<strong>{{ comment.author.get_display_name() }}</strong>
</a>
<time datetime="{{ comment.publish_date.isoformat(timespec="seconds") }}">
{{ comment.publish_date|localtime|date(DATETIME_FORMAT) }}
{{ comment.publish_date|localtime|time(DATETIME_FORMAT) }}
</time>
</div>
<div class="comment-options">
{% if user.can_edit(comment) %}
<a
class="clickable"
hx-get="{{ url('pedagogy:comment_update', comment_id=comment.id) }}"
hx-swap="outerHTML"
hx-target="#comment-{{ comment.id }}"
tooltip="{% trans %}Edit{% endtrans %}"
>
<i class="fa fa-pencil edit-action"></i>
</a>
{% endif %}
{% if not comment.is_reported %}
<a
class="clickable"
hx-get="{{ url('pedagogy:comment_report', comment_id=comment.id) }}"
hx-swap="outerHTML"
hx-target="#comment-{{ comment.id }}"
tooltip="{% trans %}Report{% endtrans %}"
>
<i class="fa fa-exclamation delete-action"></i>
</a>
{% endif %}
{% if user.has_perm("pedagogy.delete_uecomment") %}
<a
href="{{ url("pedagogy:comment_delete", comment_id=comment.id) }}"
tooltip="{% trans %}Delete{% endtrans %}"
>
<i class="fa fa-trash-can delete-action"></i>
</a>
{% endif %}
</div>
</div>
<div class="comment-stars">
<div>
<span>{% trans %}Global grade{% endtrans %}</span>
<span>{{ display_star(comment.grade_global) }}</span>
</div>
<div>
<span>{% trans %}Utility{% endtrans %}</span>
<span>{{ display_star(comment.grade_utility) }}</span>
</div>
<div>
<span>{% trans %}Interest{% endtrans %}</span>
<span>{{ display_star(comment.grade_interest) }}</span>
</div>
<div>
<span>{% trans %}Teaching{% endtrans %}</span>
<span>{{ display_star(comment.grade_teaching) }}</span>
</div>
<div>
<span>{% trans %}Workload{% endtrans %}</span>
<span>{{ display_star(comment.grade_work_load) }}</span>
</div>
</div>
<div class="comment-content">
{{ comment.comment|markdown }}
</div>
</article>
{%- endfor -%}
</section>
@@ -0,0 +1,20 @@
<div class="info-container-item">
<span>{% trans %}Global grade{% endtrans %}</span>
<span>{{ display_star(object.grade_global_average) }}</span>
</div>
<div class="info-container-item">
<span>{% trans %}Utility{% endtrans %}</span>
<span>{{ display_star(object.grade_utility_average) }}</span>
</div>
<div class="info-container-item">
<span>{% trans %}Interest{% endtrans %}</span>
<span>{{ display_star(object.grade_interest_average) }}</span>
</div>
<div class="info-container-item">
<span>{% trans %}Teaching{% endtrans %}</span>
<span>{{ display_star(object.grade_teaching_average) }}</span>
</div>
<div class="info-container-item">
<span>{% trans %}Workload{% endtrans %}</span>
<span>{{ display_star(object.grade_work_load_average) }}</span>
</div>
@@ -0,0 +1,25 @@
{# A few hx-partials for swapping a few parts of the main ue_detail.jinja #}
{% from "pedagogy/macros.jinja" import display_star %}
<hx-partial id="ue-grade">
{% include "pedagogy/fragments/ue_detail/grade.jinja" %}
</hx-partial>
<hx-partial id="comment-form">
{% if object.has_user_already_commented(user) %}
<em>
{% trans trimmed %}
You already posted a comment on this UE.
If you want to comment again, please modify or delete your previous comment.
{% endtrans %}
</em>
<br>
{% elif user.has_perm("pedagogy.add_uecomment") %}
{{ add_comment_form }}
{% endif %}
</hx-partial>
<hx-partial id="comments" hx-swap="innerMorph">
{% include "pedagogy/fragments/ue_detail/comments.jinja" %}
</hx-partial>
@@ -1,91 +0,0 @@
{% from "pedagogy/macros.jinja" import display_star %}
{% from "core/macros.jinja" import user_profile_link %}
{% if comments %}
<h2>{% trans %}Comments{% endtrans %}</h2>
<br>
{% endif %}
<section>
{% for comment in comments %}
<div id="comment-{{ comment.id }}" class="comment-container">
<div class="grade-block">
<div class="grade-type">
<p>{% trans %}Global grade{% endtrans %}</p>
<p>{% trans %}Utility{% endtrans %}</p>
<p>{% trans %}Interest{% endtrans %}</p>
<p>{% trans %}Teaching{% endtrans %}</p>
<p>{% trans %}Work load{% endtrans %}</p>
</div>
<div class="grade-stars">
<p>{{ display_star(comment.grade_global) }}</p>
<p>{{ display_star(comment.grade_utility) }}</p>
<p>{{ display_star(comment.grade_interest) }}</p>
<p>{{ display_star(comment.grade_teaching) }}</p>
<p>{{ display_star(comment.grade_work_load) }}</p>
</div>
<div class="grade-extension"></div>
</div>
<div class="comment">
<div class="anchor">
<a href="{{ url('pedagogy:ue_detail', ue_id=ue.id) }}#comment-{{ comment.id }}"><i class="fa fa-paragraph"></i></a>
</div>
{{ comment.comment|markdown }}
</div>
<div class="info">
{% if comment.is_reported %}
<p class="status-reported">
{% trans %}This comment has been reported{% endtrans %}
</p>
{% endif %}
{% if comment.author_id == user.id or user.has_perm("pedagogy.change_comment") %}
<button
class="btn btn-orange action"
hx-get="{{ url('pedagogy:comment_update', comment_id=comment.id) }}"
hx-swap="outerHTML"
hx-target="#comment-{{ comment.id }}"
>
<i class="fa fa-pencil"></i> {% trans %}Edit{% endtrans %}
</button>
{% endif %}
{% if comment.author_id == user.id or user.has_perm("pedagogy.delete_comment") %}
<form class="action"
hx-post="{{ url('pedagogy:comment_delete', comment_id=comment.id) }}"
hx-confirm='{% trans obj=object %}Are you sure you want to delete "{{ obj }}"?{% endtrans %}'
hx-swap="outerHTML"
hx-target="#comment-{{ comment.id }}"
>
{% csrf_token %}
<button class="btn btn-red action">
<i class="fa fa-trash-can"></i> {% trans %}Delete{% endtrans %}
</button>
</form>
{% endif %}
</div>
<div class="comment-end-bar">
<div class="report">
<p>
<a
hx-get="{{ url('pedagogy:comment_report', comment_id=comment.id) }}"
hx-swap="outerHTML"
hx-target="#comment-{{ comment.id }}"
>
{% trans %}Report this comment{% endtrans %}
</a>
</p>
</div>
<div class="date"><p>{{ comment.publish_date.strftime('%d/%m/%Y') }}</p></div>
<div class="author"><p>{{ user_profile_link(comment.author) }}</p></div>
</div>
</div>
{% endfor %}
</section>
@@ -1,10 +0,0 @@
{% if object.has_user_already_commented(user) %}
<div class="leave-comment-not-allowed">
<p>{% trans %}You already posted a comment on this UE. If you want to comment again, please modify or delete your previous comment.{% endtrans %}</p>
</div>
<br>
{% endif %}
{% if not object.has_user_already_commented(user) and user.has_perm("pedagogy.add_uecomment") %}
{{ add_comment_form }}
{% endif %}
@@ -1,27 +0,0 @@
<div class="ue-details-container">
<div class="grade">
<p>{% trans %}Global grade{% endtrans %}</p>
<p>{% trans %}Utility{% endtrans %}</p>
<p>{% trans %}Interest{% endtrans %}</p>
<p>{% trans %}Teaching{% endtrans %}</p>
<p>{% trans %}Work load{% endtrans %}</p>
</div>
<div class="grade-stars">
<p>{{ display_star(object.grade_global_average) }}</p>
<p>{{ display_star(object.grade_utility_average) }}</p>
<p>{{ display_star(object.grade_interest_average) }}</p>
<p>{{ display_star(object.grade_teaching_average) }}</p>
<p>{{ display_star(object.grade_work_load_average) }}</p>
</div>
<div class="ue-infos">
<p><b>{% trans %}Objectives{% endtrans %}</b></p>
<p>{{ object.objectives|markdown }}</p>
<p><b>{% trans %}Program{% endtrans %}</b></p>
<p>{{ object.program|markdown }}</p>
<p><b>{% trans %}Earned skills{% endtrans %}</b></p>
<p>{{ object.skills|markdown }}</p>
<p><b>{% trans %}Key concepts{% endtrans %}</b></p>
<p>{{ object.key_concepts|markdown }}</p>
<p><b>{% trans %}UE manager: {% endtrans %}</b>{{ object.manager }}</p>
</div>
</div>
-3
View File
@@ -1,5 +1,4 @@
{% macro display_star(grade) -%} {% macro display_star(grade) -%}
{% if grade >= 0 %} {% if grade >= 0 %}
{% for i in range(5) %} {% for i in range(5) %}
{% if i <= grade %} {% if i <= grade %}
@@ -8,9 +7,7 @@
<span class="fa-solid fa-star pedagogy star-not-checked grade-with-star"></span> <span class="fa-solid fa-star pedagogy star-not-checked grade-with-star"></span>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<span class="pedagogy grade-without-star">{{ grade }}/5</span>
{% else %} {% else %}
<span class="grade-text"> {% trans %} not rated {% endtrans %} </span> <span class="grade-text"> {% trans %} not rated {% endtrans %} </span>
{% endif %} {% endif %}
{%- endmacro %} {%- endmacro %}
+70 -65
View File
@@ -1,91 +1,96 @@
{% extends "core/base.jinja" %}
{% from "pedagogy/macros.jinja" import display_star %} {% from "pedagogy/macros.jinja" import display_star %}
{% if is_fragment %}
<hx-partial id="ue-grade"> {% block additional_css %}
{% include "pedagogy/fragments/ue_details/grade.jinja" %}
</hx-partial>
<hx-partial id="comment-form">
{% include "pedagogy/fragments/ue_details/form.jinja" %}
</hx-partial>
<hx-partial id="comments" hx-swap="innerMorph">
{% include "pedagogy/fragments/ue_details/comments.jinja" %}
</hx-partial>
{% else %}
{% extends "core/base.jinja" %}
{% block additional_css %}
<link rel="stylesheet" href="{{ static('pedagogy/css/pedagogy.scss') }}"> <link rel="stylesheet" href="{{ static('pedagogy/css/pedagogy.scss') }}">
{% endblock %} {% endblock %}
{% block title %} {% block title %}
{% trans %}UE Details{% endtrans %} {% trans %}UE Details{% endtrans %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h1>{{ object.code }}</h1>
<div class="pedagogy"> <h2 class="margin-bottom">{{ object.title }}</h2>
<div id="ue_detail"> <div class="pedagogy" id="ue_detail">
<button onclick='(function(){ <div class="ue-infos">
// If comes from the guide page, go back with history <div class="infos-column">
if (document.referrer.replace(/\?(.+)/gm,"").endsWith(`{{ url("pedagogy:guide") }}`)){ <aside class="info-container">
window.history.back(); <div class="info-container-item">
return; <div>{% trans %}Category{% endtrans %}</div>
} <div>{{ object.credit_type }}</div>
// Simply goes to the guide page
window.location.href = `{{ url("pedagogy:guide") }}`;
})()' hidden>{% trans %}Back{% endtrans %}</button>
<h1>{{ object.code }} - {{ object.title }}</h1>
<br>
<div class="ue-quick-info-container">
<div class="hours-cm">
<b>{% trans %}CM: {% endtrans %}</b>{{ object.hours_CM }}
</div> </div>
<div class="hours-td"> <div class="info-container-item">
<b>{% trans %}TD: {% endtrans %}</b>{{ object.hours_TD }} <div>{% trans %}Credits{% endtrans %}</div>
<div>{{ object.credits }}</div>
</div> </div>
<div class="hours-tp"> <hr>
<b>{% trans %}TP: {% endtrans %}</b>{{ object.hours_TP }} <div class="info-container-item">
<div>Cours magistraux</div>
<div>{{ object.hours_CM }}h</div>
</div> </div>
<div class="hours-te"> <div class="info-container-item">
<b>{% trans %}TE: {% endtrans %}</b>{{ object.hours_TE }} <div>Travaux dirigés</div>
<div>{{ object.hours_TD }}h</div>
</div> </div>
<div class="hours-the"> <div class="info-container-item">
<b>{% trans %}THE: {% endtrans %}</b>{{ object.hours_THE }} <div>Travaux pratiques</div>
<div>{{ object.hours_TP }}h</div>
</div> </div>
<div class="info-container-item">
<div class="department"> <div>Travail hors encadrement</div>
{{ object.department }} <div>{{ object.hours_THE }}h</div>
</div> </div>
<div class="credit-type"> <div class="info-container-item">
{{ object.credit_type }} <div>Cours magistraux</div>
<div>{{ object.hours_TE }}h</div>
</div> </div>
<div class="semester"> <hr>
{{ object.get_semester_display() }} <div class="info-container-item">
<div>{% trans %}Availability{% endtrans %}</div>
<div>{{ object.get_semester_display() }}</div>
</div> </div>
<hr>
<div class="info-container-item">
<div>{% trans %}Manager{% endtrans %}</div>
<div>{{ object.manager }}</div>
</div> </div>
</aside>
<br> <aside class="info-container" id="ue-grade">
{% include "pedagogy/fragments/ue_detail/grade.jinja" %}
<div id="ue-grade"> </aside>
{% include "pedagogy/fragments/ue_details/grade.jinja" %} </div>
<section class="ue-main-infos">
<h3>{% trans %}Objectives{% endtrans %}</h3>
<p>{{ object.objectives|markdown }}</p>
<h3>{% trans %}Program{% endtrans %}</h3>
<p>{{ object.program|markdown }}</p>
<h3>{% trans %}Earned skills{% endtrans %}</h3>
<p>{{ object.skills|markdown }}</p>
<h3>{% trans %}Key concepts{% endtrans %}</h3>
<p>{{ object.key_concepts|markdown }}</p>
</section>
</div> </div>
<br> <br>
<div id="comment-form"> <div id="comment-form">
{% include "pedagogy/fragments/ue_details/form.jinja" %} {% if object.has_user_already_commented(user) %}
<em>
{% trans trimmed %}
You already posted a comment on this UE.
If you want to comment again, please modify or delete your previous comment.
{% endtrans %}
</em>
<br>
{% elif user.has_perm("pedagogy.add_uecomment") %}
{{ add_comment_form }}
{% endif %}
</div> </div>
<div id="comments"> <div id="comments">
{% include "pedagogy/fragments/ue_details/comments.jinja" %} {% include "pedagogy/fragments/ue_detail/comments.jinja" %}
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% endif %}
+10 -7
View File
@@ -88,16 +88,19 @@ class UEDetailView(
model = UE model = UE
pk_url_kwarg = "ue_id" pk_url_kwarg = "ue_id"
template_name = "pedagogy/ue_detail.jinja"
permission_required = "pedagogy.view_ue" permission_required = "pedagogy.view_ue"
fragments = { fragments = {"add_comment_form": UECommentCreateView}
"add_comment_form": UECommentCreateView,
} def get_template_names(self) -> list[str]:
is_fragment = self.request.headers.get("HX-Request", False)
return (
["pedagogy/fragments/ue_detail/ue_detail.jinja"]
if is_fragment
else ["pedagogy/ue_detail.jinja"]
)
def get_fragment_data(self): def get_fragment_data(self):
return { return {"add_comment_form": {"ue_id": self.object.id}}
"add_comment_form": {"ue_id": self.object.id},
}
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | { return super().get_context_data(**kwargs) | {
-2
View File
@@ -417,8 +417,6 @@ SITH_FORUM_PAGE_LENGTH = 30
SITH_SAS_ROOT_DIR_ID = env.int("SITH_SAS_ROOT_DIR_ID", default=4) SITH_SAS_ROOT_DIR_ID = env.int("SITH_SAS_ROOT_DIR_ID", default=4)
SITH_SAS_IMAGES_PER_PAGE = 60 SITH_SAS_IMAGES_PER_PAGE = 60
SITH_CGU_FILE_ID = env.int("SITH_CGU_FILE_ID", default=5)
SITH_PROFILE_DEPARTMENTS = [ SITH_PROFILE_DEPARTMENTS = [
("TC", _("TC")), ("TC", _("TC")),
("IMSI", _("IMSI")), ("IMSI", _("IMSI")),