Merge branch 'frontend' of https://scodoc.org/git/iziram/ScoDoc into revamp

This commit is contained in:
Emmanuel Viennet 2024-08-22 20:10:05 +02:00
commit b448e32f8a
17 changed files with 221 additions and 50 deletions

View File

@ -25,9 +25,7 @@
# #
############################################################################## ##############################################################################
"""Ajout/Modification/Suppression UE """Ajout/Modification/Suppression UE"""
"""
import re import re

View File

@ -243,9 +243,10 @@ print {
/*Mobile Navbar*/ /*Mobile Navbar*/
#logo-scodoc { #logo-scodoc {
--size: 48px; /* base image : logo_rectangle.png 527x192 */
--size: 64px;
height: calc(var(--size) / 2.744);
width: var(--size); width: var(--size);
height: var(--size);
margin: 4px; margin: 4px;
cursor: pointer; cursor: pointer;
} }
@ -260,7 +261,7 @@ print {
/* From https://css.glass */ /* From https://css.glass */
background: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.2);
border-radius: 16px; border-radius: 0 0 16px 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px); backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px);
@ -269,4 +270,10 @@ print {
body { body {
position: relative; position: relative;
}
.no-scroll {
overflow: hidden !important;
margin: 0 !important;
height: 100vh !important;
} }

View File

@ -0,0 +1,98 @@
/* == Gestion des styles pour les mobiles == */
@media screen and (max-width: 768px) {
/* <== Module Assiduité ==> */
#ajout-assiduite-etud .description>textarea,
#ajout-justificatif-etud .raison>textarea {
width: 90%;
}
#modimpl,
#moduleimpl_select {
max-width: 200px;
}
#timeline {
flex-wrap: wrap-reverse;
}
.time-buttons {
display: flex;
justify-content: space-evenly;
}
#timeline .inputs {
flex-direction: row;
justify-content: space-evenly;
width: 100%;
padding: 8px;
}
#timeline .inputs>input {
width: 100%;
text-align: center;
}
.timeline-container .period-handle::before {
width: 40px !important;
height: 100% !important;
content: "";
display: block;
background-color: red;
border-radius: 12px;
opacity: 0.5;
position: absolute;
top: 0;
mix-blend-mode: color-dodge;
}
.timeline-container .period-handle.left::before {
transform: translateX(-50%);
left: 0;
}
.timeline-container .period-handle.right::before {
transform: translateX(50%);
right: 0;
}
.selectors .infos {
flex-direction: column;
}
.selectors .infos .date-input {
display: flex;
flex-direction: row;
justify-content: space-evenly;
}
.mass-selection {
flex-wrap: wrap;
}
.etud_row {
grid-template-columns: 2% 20% auto 25% !important;
max-width: 350px;
gap: 8px;
}
.etud_row .assiduites_bar {
grid-column: 4 !important;
grid-row: 1;
}
.etud_row .btns_field.single {
grid-column: 3 !important;
grid-row: 1;
}
.rbtn::before {
--size: 35px;
width: var(--size) !important;
height: var(--size) !important;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -95,8 +95,8 @@ div.submit > input {
{{ render_field_errors(form, 'est_just') }} {{ render_field_errors(form, 'est_just') }}
</div> </div>
{# Description #} {# Description #}
<div> <div class="description">
<div>{{ form.description.label }}</div> {{ form.description.label }}
{{ form.description() }} {{ form.description() }}
{{ render_field_errors(form, 'description') }} {{ render_field_errors(form, 'description') }}
</div> </div>

View File

@ -106,7 +106,7 @@ div.submit > input {
{{ render_field_errors(form, 'etat') }} {{ render_field_errors(form, 'etat') }}
</div> </div>
{# Raison #} {# Raison #}
<div> <div class="raison">
{% if (not justif) or can_view_justif_detail %} {% if (not justif) or can_view_justif_detail %}
<div>{{ form.raison.label }}</div> <div>{{ form.raison.label }}</div>
{{ form.raison() }} {{ form.raison() }}

View File

@ -76,6 +76,7 @@ Bilan assiduité de {{sco.etud.nomprenom}}
id="stats_date_debut" value="{{date_debut}}"></label> id="stats_date_debut" value="{{date_debut}}"></label>
<label class="stats-label"> Date de fin <input type="text" class="datepicker" name="stats_date_fin" <label class="stats-label"> Date de fin <input type="text" class="datepicker" name="stats_date_fin"
id="stats_date_fin" value="{{date_fin}}"></label> id="stats_date_fin" value="{{date_fin}}"></label>
<br mobile="true">
<button onclick="stats()">Actualiser</button> <button onclick="stats()">Actualiser</button>
</div> </div>

View File

@ -15,12 +15,15 @@ Calendrier de l'assiduité
<h2>Assiduité de {{sco.etud.html_link_fiche()|safe}}</h2> <h2>Assiduité de {{sco.etud.html_link_fiche()|safe}}</h2>
<div class="options"> <div class="options">
<input type="checkbox" id="show_pres" name="show_pres" class="memo" {{'checked' if show_pres else '' }}><label <label for="show_pres">afficher les présences
for="show_pres">afficher les présences</label> <input type="checkbox" id="show_pres" name="show_pres" class="memo" {{'checked' if show_pres else '' }}>
<input type="checkbox" name="show_reta" id="show_reta" class="memo" {{'checked' if show_reta else '' }}><label </label>
for="show_reta">afficher les retards</label> <label for="show_reta">afficher les retards
<input type="checkbox" name="mode_demi" id="mode_demi" class="memo" {{'checked' if mode_demi else '' }}><label <input type="checkbox" name="show_reta" id="show_reta" class="memo" {{'checked' if show_reta else '' }}>
for="mode_demi">mode demi journée</label> </label>
<label for="mode_demi">mode demi journée
<input type="checkbox" name="mode_demi" id="mode_demi" class="memo"{{'checked' if mode_demi else '' }}>
</label>
</div> </div>
<div class="cal"> <div class="cal">
@ -86,15 +89,6 @@ Calendrier de l'assiduité
max-width: var(--sco-content-max-width); max-width: var(--sco-content-max-width);
} }
.calendrier {
display: flex;
justify-content: center;
overflow-x: scroll;
border: 1px solid #444;
border-radius: 12px;
margin-bottom: 12px;
}
.assi_case { .assi_case {
display: flex; display: flex;
width: 100%; width: 100%;

View File

@ -115,12 +115,18 @@
padding: 5px; padding: 5px;
border-radius: 5px; border-radius: 5px;
text-decoration: none; text-decoration: none;
z-index: 100;
} }
html{ html{
scroll-behavior: smooth !important; scroll-behavior: smooth !important;
} }
.date-input{
display: flex;
gap: 4px;
}
</style> </style>
{% endblock styles %} {% endblock styles %}
@ -152,20 +158,22 @@
<fieldset class="selectors"> <fieldset class="selectors">
<div class="infos"> <div class="infos">
<div class="infos-button">Groupes&nbsp;: {{grp|safe}}</div> <div class="infos-button">Groupes&nbsp;: {{grp|safe}}</div>
<div> <div class="date-input">
<button class="btn_date btn btn-secondary" onclick="jourSuivant(true)"> <button class="btn_date btn btn-secondary" onclick="jourSuivant(true)">
&LeftArrowBar; &LeftArrowBar;
</button> </button>
<input type="text" name="date" id="date" class="datepicker" value="{{date}}"> <div>
<input type="text" name="date" id="date" class="datepicker" value="{{date}}">
</div>
<button class="btn_date btn btn-secondary" onclick="jourSuivant(false)">
&RightArrowBar;
</button>
</div> </div>
<button class="btn_date btn btn-secondary" onclick="jourSuivant(false)">
&RightArrowBar;
</button>
</div> </div>
</fieldset> </fieldset>
<div style="display: {{'none' if readonly == 'true' else 'block'}};"> <div style="display: {{'none' if readonly == 'true' else 'block'}};">
{{timeline|safe}} {{timeline|safe}}
<div> <div class="time-buttons">
<button class=" btn btn-secondary" onclick="setPeriodValues(t_start, t_mid)">Matin</button> <button class=" btn btn-secondary" onclick="setPeriodValues(t_start, t_mid)">Matin</button>
<button class=" btn btn-secondary" onclick="setPeriodValues(t_mid, t_end)">Après-Midi</button> <button class=" btn btn-secondary" onclick="setPeriodValues(t_mid, t_end)">Après-Midi</button>
</div> </div>

View File

@ -58,7 +58,7 @@
<!-- Mettre les flèches --> <!-- Mettre les flèches -->
{% if total_pages > 1 %} {% if total_pages > 1 %}
<ul class="pagination"> <ul class="pagination">
<li class=""> <li class="{{'disabled' if options.page == 1 else ''}}">
<a onclick="navigateToPage({{options.page - 1}})">&lt;</a> <a onclick="navigateToPage({{options.page - 1}})">&lt;</a>
</li> </li>
<!-- Toujours afficher la première page --> <!-- Toujours afficher la première page -->
@ -91,7 +91,7 @@
<li class="{% if options.page == total_pages %}active{% endif %}"> <li class="{% if options.page == total_pages %}active{% endif %}">
<a onclick="navigateToPage({{total_pages}})">{{ total_pages }}</a> <a onclick="navigateToPage({{total_pages}})">{{ total_pages }}</a>
</li> </li>
<li class=""> <li class="{{'disabled' if options.page == total_pages else ''}}">
<a onclick="navigateToPage({{options.page + 1}})">&gt;</a> <a onclick="navigateToPage({{options.page + 1}})">&gt;</a>
</li> </li>
</ul> </ul>
@ -235,7 +235,30 @@
max-width: fit-content; max-width: fit-content;
} }
.pagination li{ .pagination li>*{
cursor: pointer; cursor: pointer;
/*Style pour les boutons de pagination*/
border: 1px solid #ccc;
background-color: #f1f1f1;
padding: 8px 16px;
font-size: 16px;
border-radius: 4px;
margin: 8px 1px;
}
.pagination li:hover >a, .pagination li.active>*{
/*Style pour les boutons actifs*/
background-color: var(--sco-color-ues);
color: white !important;
}
.pagination li.disabled>*{
/*Style pour les boutons désactivés*/
opacity: 0.5;
cursor: default;
pointer-events: none;
user-select: none;
} }
</style> </style>

View File

@ -3,7 +3,7 @@
<input type="text" name="deb" id="deb" class="timepicker"> <input type="text" name="deb" id="deb" class="timepicker">
<input type="text" name="fin" id="fin" class="timepicker"> <input type="text" name="fin" id="fin" class="timepicker">
</div> </div>
<div class="timeline-container"> <div class="timeline-container" desktop="true">
<div class="period" style="left: 0%; width: 20%"> <div class="period" style="left: 0%; width: 20%">
<div class="period-handle left"></div> <div class="period-handle left"></div>
<div class="period-handle right"></div> <div class="period-handle right"></div>
@ -12,8 +12,6 @@
</div> </div>
</div> </div>
<script> <script>
const timelineContainer = document.querySelector(".timeline-container"); const timelineContainer = document.querySelector(".timeline-container");
const periodTimeLine = document.querySelector(".period"); const periodTimeLine = document.querySelector(".period");
const t_start = {{ t_start }}; const t_start = {{ t_start }};
@ -27,6 +25,8 @@
let handleMoving = false; let handleMoving = false;
const isMobile = window.matchMedia("(max-width: 768px)").matches;
// Création des graduations de la timeline // Création des graduations de la timeline
// On créé des grandes graduations pour les heures // On créé des grandes graduations pour les heures
// On créé des petites graduations pour les "tick" // On créé des petites graduations pour les "tick"
@ -44,6 +44,11 @@
tickLabel.classList.add("tick-label"); tickLabel.classList.add("tick-label");
tickLabel.style.left = `${((i - t_start) / (t_end - t_start)) * 100}%`; tickLabel.style.left = `${((i - t_start) / (t_end - t_start)) * 100}%`;
tickLabel.textContent = numberToTime(i); tickLabel.textContent = numberToTime(i);
// on retire ce qu'il y a après les : sur mobile
if (isMobile) {
tickLabel.textContent = tickLabel.textContent.split(":")[0];
}
timelineContainer.appendChild(tickLabel); timelineContainer.appendChild(tickLabel);
// Si on est pas à la fin, on ajoute les graduations intermédiaires // Si on est pas à la fin, on ajoute les graduations intermédiaires
if (i < t_end) { if (i < t_end) {

View File

@ -21,11 +21,12 @@
<style> <style>
.calendrier { .calendrier {
display: flex; display: flex;
justify-content: center; justify-content: flex-start;
overflow-x: scroll; overflow-x: scroll;
border: 1px solid #444; border: 1px solid #444;
border-radius: 12px; border-radius: 12px;
margin-bottom: 12px; margin-bottom: 12px;
padding: 4px;
} }
.mois { .mois {

View File

@ -15,8 +15,8 @@
margin-top: 10px; margin-top: 10px;
} }
.content{ .content{
width: 90%;
max-width: 1600px; max-width: 1600px;
padding: 12px;
} }
</style> </style>
{% endblock %} {% endblock %}

View File

@ -20,12 +20,6 @@
box-sizing: border-box; box-sizing: border-box;
} }
.no-scroll {
overflow: hidden !important;
margin: 0 !important;
height: 100vh !important;
}
/* CSS menu */ /* CSS menu */
.sco-formsemestre-menu { .sco-formsemestre-menu {
background-color: var(--sco-formsemestre-color-primary); background-color: var(--sco-formsemestre-color-primary);
@ -372,8 +366,6 @@
// Affichage du menu mobile au clic // Affichage du menu mobile au clic
navbarToggle.addEventListener("click", () => { navbarToggle.addEventListener("click", () => {
document.body.classList.toggle("no-scroll");
navbarMenu.classList.toggle("active"); navbarMenu.classList.toggle("active");
navbarToggle.classList.toggle("active"); navbarToggle.classList.toggle("active");
@ -385,6 +377,10 @@
// Fermeture des dropdowns // Fermeture des dropdowns
dropdownItems.forEach((item) => item.removeAttribute("open")); dropdownItems.forEach((item) => item.removeAttribute("open"));
// Blockage du scroll
toggleScroll();
}); });
// Fermeture du menu mobile au clic en dehors du menu // Fermeture du menu mobile au clic en dehors du menu
@ -393,6 +389,7 @@
navbarMenu.classList.remove("active"); navbarMenu.classList.remove("active");
navbarToggle.classList.remove("active"); navbarToggle.classList.remove("active");
navbarToggle.setAttribute("aria-expanded", "false"); navbarToggle.setAttribute("aria-expanded", "false");
toggleScroll();
} }
}); });

View File

@ -5,6 +5,7 @@
{{super()}} {{super()}}
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc.css"> <link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc.css">
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc97.css"> <link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc97.css">
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc9_mobile.css">
<link href="{{scu.STATIC_DIR}}/css/menu.css" rel="stylesheet" type="text/css" /> <link href="{{scu.STATIC_DIR}}/css/menu.css" rel="stylesheet" type="text/css" />
<link href="{{scu.STATIC_DIR}}/css/gt_table.css" rel="stylesheet" type="text/css" /> <link href="{{scu.STATIC_DIR}}/css/gt_table.css" rel="stylesheet" type="text/css" />
<link type="text/css" rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/qtip/jquery.qtip-3.0.3.min.css" /> <link type="text/css" rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/qtip/jquery.qtip-3.0.3.min.css" />
@ -21,7 +22,7 @@
<!-- sco_page revamp --> <!-- sco_page revamp -->
<div id="mobileNav" mobile="true"> <div id="mobileNav" mobile="true">
<!-- Logo ScoDoc --> <!-- Logo ScoDoc -->
<img src="{{url_for('static', filename='icons/logo.png')}}" alt="Logo ScoDoc" id="logo-scodoc"> <img src="{{url_for('static', filename='icons/logo_rectangle.png')}}" alt="Logo ScoDoc" id="logo-scodoc">
{% block mobileSemestre %} {% block mobileSemestre %}
<!-- Titre Semestre --> <!-- Titre Semestre -->
<!-- Icone Menu Semestre --> <!-- Icone Menu Semestre -->
@ -76,6 +77,8 @@
<script src="{{scu.STATIC_DIR}}/js/etud_info.js"></script> <script src="{{scu.STATIC_DIR}}/js/etud_info.js"></script>
<script src="{{scu.STATIC_DIR}}/DataTables/datatables.min.js"></script> <script src="{{scu.STATIC_DIR}}/DataTables/datatables.min.js"></script>
<script> <script>
let no_sidebar = {{ 'true' if no_sidebar else 'false' }};
window.onload = function () { window.onload = function () {
if (document.getElementById('gtrcontent')) { if (document.getElementById('gtrcontent')) {
enableTooltips("gtrcontent"); enableTooltips("gtrcontent");
@ -87,6 +90,10 @@
document.getElementById("logo-scodoc").addEventListener("click", function () { document.getElementById("logo-scodoc").addEventListener("click", function () {
toggleSidebarOffCanvas(); toggleSidebarOffCanvas();
}); });
if (no_sidebar) {
toggleSidebar();
}
}; };
const SCO_URL = "{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}"; const SCO_URL = "{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}";
function toggleSidebar() { function toggleSidebar() {

View File

@ -98,6 +98,14 @@ div.effectif {
max-width: 1024px; /* Maximum width */ max-width: 1024px; /* Maximum width */
margin: 0 auto 0 0; /* Centers divs if they are narrower than 1024px */ margin: 0 auto 0 0; /* Centers divs if they are narrower than 1024px */
} }
@media screen and (max-width: 768px) {
/*Fix for mobile*/
.cur-formsemestres {
width: auto;
}
}
.cur-formsemestre { .cur-formsemestre {
display: flex; display: flex;
align-items: center; align-items: center;
@ -143,6 +151,7 @@ div.effectif {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
font-size: 14px; font-size: 14px;
white-space: nowrap;
} }
.responsable { .responsable {
font-weight: bold; font-weight: bold;

View File

@ -124,6 +124,29 @@
const sidebar = document.querySelector('#sidebar'); const sidebar = document.querySelector('#sidebar');
const expanded = sidebar.getAttribute('aria-expanded') === 'true'; const expanded = sidebar.getAttribute('aria-expanded') === 'true';
sidebar.setAttribute('aria-expanded', !expanded); sidebar.setAttribute('aria-expanded', !expanded);
toggleScroll();
}
function toggleScroll(){
const changeScroll = (b) => {
document.querySelectorAll("body, html").forEach(el => el.classList.toggle("no-scroll", b));
}
const sidebar = document.querySelector('#sidebar');
const formSemestreMenu = document.querySelector('.sco-formsemestre-menu-menu');
const sidebarExpanded = sidebar ? sidebar.getAttribute('aria-expanded') === 'true' : false;
const formSemestreMenuExpanded = formSemestreMenu ? formSemestreMenu.classList.contains("active") : false;
let isScrollToggled = document.body.classList.contains("no-scroll");
if (isScrollToggled && !sidebarExpanded && !formSemestreMenuExpanded) {
changeScroll(false);
}
else if (!isScrollToggled && (sidebarExpanded || formSemestreMenuExpanded)) {
changeScroll(true);
}
} }
</script> </script>