forked from ScoDoc/ScoDoc
Merge branch 'iziram-sco_gen_cal'
This commit is contained in:
commit
e18c1d8fd0
@ -30,6 +30,7 @@
|
||||
Lecture et conversion des ics.
|
||||
|
||||
"""
|
||||
|
||||
from datetime import timezone
|
||||
import glob
|
||||
import os
|
||||
@ -229,7 +230,7 @@ def translate_calendar(
|
||||
heure_deb=event["heure_deb"],
|
||||
heure_fin=event["heure_fin"],
|
||||
moduleimpl_id=modimpl.id,
|
||||
jour=event["jour"],
|
||||
day=event["jour"],
|
||||
)
|
||||
if modimpl and group
|
||||
else None
|
||||
|
@ -832,7 +832,7 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str:
|
||||
<a class="stdlink" href="{
|
||||
url_for("assiduites.signal_assiduites_group",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
jour=datetime.date.today().isoformat(),
|
||||
day=datetime.date.today().isoformat(),
|
||||
formsemestre_id=formsemestre.id,
|
||||
group_ids=group.id,
|
||||
)}">
|
||||
|
@ -54,11 +54,11 @@ class Jour:
|
||||
"""
|
||||
return self.date.isocalendar()[0:2] == datetime.date.today().isocalendar()[0:2]
|
||||
|
||||
def get_date(self) -> str:
|
||||
def get_date(self, fmt=scu.DATE_FMT) -> str:
|
||||
"""
|
||||
Renvoie la date du jour au format "dd/mm/yyyy"
|
||||
Renvoie la date du jour au format fmt ou "dd/mm/yyyy" par défaut
|
||||
"""
|
||||
return self.date.strftime(scu.DATE_FMT)
|
||||
return self.date.strftime(fmt)
|
||||
|
||||
def get_html(self):
|
||||
"""
|
||||
@ -93,12 +93,22 @@ class Calendrier:
|
||||
Représente un calendrier
|
||||
Permet d'obtenir les informations sur les jours
|
||||
et générer une représentation html
|
||||
|
||||
highlight: str
|
||||
-> ["jour", "semaine", "mois"]
|
||||
permet de mettre en valeur lors du passage de la souris
|
||||
"""
|
||||
|
||||
def __init__(self, date_debut: datetime.date, date_fin: datetime.date):
|
||||
def __init__(
|
||||
self,
|
||||
date_debut: datetime.date,
|
||||
date_fin: datetime.date,
|
||||
highlight: str = None,
|
||||
):
|
||||
self.date_debut = date_debut
|
||||
self.date_fin = date_fin
|
||||
self.jours: dict[str, list[Jour]] = {}
|
||||
self.highlight: str = highlight
|
||||
|
||||
def _get_dates_between(self) -> list[datetime.date]:
|
||||
"""
|
||||
@ -130,11 +140,13 @@ class Calendrier:
|
||||
month = scu.MONTH_NAMES_ABBREV[date.month - 1]
|
||||
# Ajouter le jour à la liste correspondante au mois
|
||||
if month not in organized:
|
||||
organized[month] = []
|
||||
organized[month] = {} # semaine {22: []}
|
||||
|
||||
jour: Jour = self.instanciate_jour(date)
|
||||
|
||||
organized[month].append(jour)
|
||||
semaine = date.strftime("%G-W%V")
|
||||
if semaine not in organized[month]:
|
||||
organized[month][semaine] = []
|
||||
organized[month][semaine].append(jour)
|
||||
|
||||
self.jours = organized
|
||||
|
||||
@ -150,4 +162,53 @@ class Calendrier:
|
||||
get_html Renvoie le code html du calendrier
|
||||
"""
|
||||
self.organize_by_month()
|
||||
return render_template("calendrier.j2", calendrier=self.jours)
|
||||
return render_template(
|
||||
"calendrier.j2", calendrier=self.jours, highlight=self.highlight
|
||||
)
|
||||
|
||||
|
||||
class JourChoix(Jour):
|
||||
"""
|
||||
Représente un jour dans le calendrier pour choisir une date
|
||||
"""
|
||||
|
||||
def get_html(self):
|
||||
return ""
|
||||
|
||||
|
||||
class CalendrierChoix(Calendrier):
|
||||
"""
|
||||
Représente un calendrier pour choisir une date
|
||||
"""
|
||||
|
||||
def instanciate_jour(self, date: datetime.date) -> Jour:
|
||||
return JourChoix(date)
|
||||
|
||||
|
||||
def calendrier_choix_date(
|
||||
date_debut: datetime.date,
|
||||
date_fin: datetime.date,
|
||||
url: str,
|
||||
mode: str = "jour",
|
||||
titre: str = "Choisir une date",
|
||||
):
|
||||
"""
|
||||
Permet d'afficher un calendrier pour choisir une date et renvoyer sur une url.
|
||||
|
||||
mode : str
|
||||
- "jour" -> ajoutera "&day=yyyy-mm-dd" à l'url (ex: 2024-05-30)
|
||||
- "semaine" -> ajoutera "&week=yyyy-Www" à l'url (ex : 2024-W22)
|
||||
|
||||
titre : str
|
||||
- texte à afficher au dessus du calendrier
|
||||
"""
|
||||
|
||||
calendrier: CalendrierChoix = CalendrierChoix(date_debut, date_fin, highlight=mode)
|
||||
|
||||
return render_template(
|
||||
"choix_date.j2",
|
||||
calendrier=calendrier.get_html(),
|
||||
url=url,
|
||||
titre=titre,
|
||||
mode=mode,
|
||||
)
|
||||
|
@ -983,7 +983,7 @@ def form_choix_jour_saisie_hebdo(groups_infos, moduleimpl_id=None):
|
||||
"assiduites.signal_assiduites_group",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
group_ids=",".join(map(str,groups_infos.group_ids)),
|
||||
jour=datetime.date.today().isoformat(),
|
||||
day=datetime.date.today().isoformat(),
|
||||
formsemestre_id=groups_infos.formsemestre_id,
|
||||
moduleimpl_id="" if moduleimpl_id is None else moduleimpl_id
|
||||
)
|
||||
|
@ -346,7 +346,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
f"""
|
||||
<span class="moduleimpl_abs_link"><a class="stdlink" href="{
|
||||
url_for("assiduites.signal_assiduites_group", scodoc_dept=g.scodoc_dept)
|
||||
}?group_ids={group_id}&jour={
|
||||
}?group_ids={group_id}&day={
|
||||
datetime.date.today().isoformat()
|
||||
}&formsemestre_id={formsemestre.id}
|
||||
&moduleimpl_id={moduleimpl_id}
|
||||
|
@ -1,10 +1,11 @@
|
||||
<div class="calendrier">
|
||||
{% for mois,jours in calendrier.items() %}
|
||||
<div class="mois">
|
||||
{% for mois,semaines in calendrier.items() %}
|
||||
<div class="mois {{'highlight' if highlight=='mois'}}">
|
||||
<h3>{{mois}}</h3>
|
||||
<div class="jours">
|
||||
{% for jour in jours %}
|
||||
<div class="jour {{jour.get_class()}}">
|
||||
{% for semaine in semaines %}
|
||||
<div class="jours {{'highlight' if highlight=='semaine'}}" week_index="{{semaine}}">
|
||||
{% for jour in semaines[semaine] %}
|
||||
<div class="jour {{jour.get_class()}} {{'highlight' if highlight=='jour'}}" date="{{jour.get_date('%Y-%m-%d')}}">
|
||||
<span class="nom">{{jour.get_nom()}}</span>
|
||||
<div class="contenu">
|
||||
{{jour.get_html() | safe}}
|
||||
@ -12,6 +13,7 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@ -84,5 +86,8 @@
|
||||
border-left: solid 3px var(--couleur);
|
||||
border-right: solid 3px var(--couleur);
|
||||
}
|
||||
.highlight:hover{
|
||||
border: solid 3px yellow;
|
||||
}
|
||||
|
||||
</style>
|
62
app/templates/choix_date.j2
Normal file
62
app/templates/choix_date.j2
Normal file
@ -0,0 +1,62 @@
|
||||
{% extends "sco_page.j2" %}
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
|
||||
<style>
|
||||
.highlight {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
.highlight * {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
#gtrcontent h2.titre {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.content{
|
||||
width: 90%;
|
||||
max-width: 1600px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block app_content %}
|
||||
<div class="content">
|
||||
<h2 class="titre">{{titre}}</h2>
|
||||
{{calendrier | safe}}
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock app_content %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
|
||||
<script>
|
||||
|
||||
const mode = "{{mode}}";
|
||||
const url = new URL(window.location.origin + "{{url | safe}}");
|
||||
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
const highlight = document.querySelectorAll(".highlight");
|
||||
highlight.forEach((el)=>{
|
||||
el.addEventListener("click", (e)=>{
|
||||
if (mode == "jour"){
|
||||
const date = el.getAttribute("date");
|
||||
url.searchParams.set("day", date);
|
||||
}
|
||||
if (mode == "semaine"){
|
||||
const date = el.getAttribute("week_index");
|
||||
url.searchParams.set("week", date);
|
||||
}
|
||||
|
||||
window.location.href = url;
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock scripts %}
|
@ -894,63 +894,6 @@ def calendrier_assi_etud():
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/choix_date", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.AbsChange)
|
||||
def choix_date() -> str:
|
||||
"""
|
||||
choix_date Choix de la date pour la saisie des assiduités
|
||||
|
||||
Route utilisée uniquement si la date courante n'est pas dans le semestre
|
||||
concerné par la requête vers une des pages suivantes :
|
||||
- saisie_assiduites_group
|
||||
"""
|
||||
formsemestre_id = request.args.get("formsemestre_id")
|
||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
|
||||
group_ids = request.args.get("group_ids")
|
||||
moduleimpl_id = request.args.get("moduleimpl_id")
|
||||
form = ChoixDateForm(request.form)
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.cancel.data:
|
||||
return redirect(url_for("scodoc.index"))
|
||||
# Vérifier si date dans semestre
|
||||
ok: bool = False
|
||||
try:
|
||||
date: datetime.date = datetime.datetime.strptime(
|
||||
form.date.data, scu.DATE_FMT
|
||||
).date()
|
||||
if date < formsemestre.date_debut or date > formsemestre.date_fin:
|
||||
form.set_error(
|
||||
"La date sélectionnée n'est pas dans le semestre.", form.date
|
||||
)
|
||||
else:
|
||||
ok = True
|
||||
except ValueError:
|
||||
form.set_error("Date invalide", form.date)
|
||||
|
||||
if ok:
|
||||
return redirect(
|
||||
url_for(
|
||||
"assiduites.signal_assiduites_group",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id,
|
||||
group_ids=group_ids,
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
jour=date.isoformat(),
|
||||
)
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"assiduites/pages/choix_date.j2",
|
||||
form=form,
|
||||
sco=ScoData(formsemestre=formsemestre),
|
||||
deb=formsemestre.date_debut.strftime(scu.DATE_FMT),
|
||||
fin=formsemestre.date_fin.strftime(scu.DATE_FMT),
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/signal_assiduites_group")
|
||||
@scodoc
|
||||
@permission_required(Permission.AbsChange)
|
||||
@ -965,7 +908,7 @@ def signal_assiduites_group():
|
||||
# formsemestre_id est optionnel si modimpl est indiqué
|
||||
formsemestre_id: int = request.args.get("formsemestre_id", -1)
|
||||
moduleimpl_id: int = request.args.get("moduleimpl_id")
|
||||
date: str = request.args.get("jour", datetime.date.today().isoformat())
|
||||
date: str = request.args.get("day", datetime.date.today().isoformat())
|
||||
heures: list[str] = [
|
||||
request.args.get("heure_deb", ""),
|
||||
request.args.get("heure_fin", ""),
|
||||
@ -1028,14 +971,23 @@ def signal_assiduites_group():
|
||||
|
||||
if real_date < formsemestre.date_debut or real_date > formsemestre.date_fin:
|
||||
# Si le jour est hors semestre, renvoyer vers choix date
|
||||
return redirect(
|
||||
url_for(
|
||||
"assiduites.choix_date",
|
||||
formsemestre_id=formsemestre_id,
|
||||
group_ids=group_ids,
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
flash(
|
||||
"La date sélectionnée n'est pas dans le semestre. Choisissez une autre date."
|
||||
)
|
||||
|
||||
return sco_gen_cal.calendrier_choix_date(
|
||||
formsemestre.date_debut,
|
||||
formsemestre.date_fin,
|
||||
url=url_for(
|
||||
"assiduites.signal_assiduites_group",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
)
|
||||
formsemestre_id=formsemestre_id,
|
||||
group_ids=",".join(group_ids),
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
day="placeholder",
|
||||
),
|
||||
mode="jour",
|
||||
titre="Choix de la date",
|
||||
)
|
||||
|
||||
# --- Restriction en fonction du moduleimpl_id ---
|
||||
@ -2038,7 +1990,23 @@ def signal_assiduites_hebdo():
|
||||
# les chaines sont triables par ordre alphanumérique croissant
|
||||
# et produiront le même ordre que les dates par ordre chronologique croissant
|
||||
if week < fs_deb_iso8601 or week > fs_fin_iso8601:
|
||||
raise ScoValueError("Semaine hors du semestre", dest_url=request.referrer)
|
||||
flash(
|
||||
"La semaine n'est pas dans le semestre, choisissez la semaine sur laquelle saisir l'assiduité"
|
||||
)
|
||||
return sco_gen_cal.calendrier_choix_date(
|
||||
date_debut=formsemestre.date_debut,
|
||||
date_fin=formsemestre.date_fin,
|
||||
url=url_for(
|
||||
"assiduites.signal_assiduites_hebdo",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id,
|
||||
group_ids=group_ids,
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
week="placeholder",
|
||||
),
|
||||
mode="semaine",
|
||||
titre="Choix de la semaine",
|
||||
)
|
||||
|
||||
# Vérification des groupes
|
||||
group_ids = group_ids.split(",") if group_ids != "" else []
|
||||
|
Loading…
Reference in New Issue
Block a user