From c9ca97df6e3d51505ce4bb502aa049c58e3444fe Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 22 Jul 2024 16:53:50 +0200 Subject: [PATCH 01/55] WIP: revamp html/css: sidebar, hamburger, templates --- app/models/events.py | 2 +- app/scodoc/sco_saisie_excel.py | 2 +- app/scodoc/sco_saisie_notes.py | 2 +- app/static/css/scodoc.css | 6 +- app/static/css/scodoc97.css | 207 ++++++++++++++++++++++++++++++++ app/static/icons/back.svg | 1 + app/templates/hamburger_menu.j2 | 5 + app/templates/sco_page.j2 | 83 ++++++++++--- app/templates/sco_page_dept.j2 | 12 ++ app/templates/scolar/index.j2 | 2 +- app/templates/sidebar.j2 | 58 +++++---- app/views/notes.py | 8 +- app/views/scolar.py | 1 + sco_version.py | 2 +- 14 files changed, 343 insertions(+), 48 deletions(-) create mode 100644 app/static/css/scodoc97.css create mode 100644 app/static/icons/back.svg create mode 100644 app/templates/hamburger_menu.j2 create mode 100644 app/templates/sco_page_dept.j2 diff --git a/app/models/events.py b/app/models/events.py index 3e6c2bf7..c65ea0ee 100644 --- a/app/models/events.py +++ b/app/models/events.py @@ -109,7 +109,7 @@ class ScolarNews(db.Model): ) def __str__(self): - "'Chargement notes dans Stage (S3 FI) par Aurélie Dupont'" + "exemple: 'Notes dans Stage (S3 FI) par Aurélie Dupont'" formsemestre = self.get_news_formsemestre() user = User.query.filter_by(user_name=self.authenticated_user).first() diff --git a/app/scodoc/sco_saisie_excel.py b/app/scodoc/sco_saisie_excel.py index 38f65243..d725dae5 100644 --- a/app/scodoc/sco_saisie_excel.py +++ b/app/scodoc/sco_saisie_excel.py @@ -651,7 +651,7 @@ def do_evaluations_upload_xls( ScolarNews.add( typ=ScolarNews.NEWS_NOTE, obj=obj_id, - text=f"""Chargement notes dans {modules_str}""", + text=f"""Notes dans {modules_str}""", url=status_url, max_frequency=10 * 60, # 10 minutes ) diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py index cad79c3f..86b2cc30 100644 --- a/app/scodoc/sco_saisie_notes.py +++ b/app/scodoc/sco_saisie_notes.py @@ -1047,7 +1047,7 @@ def save_notes( ScolarNews.add( typ=ScolarNews.NEWS_NOTE, obj=evaluation.moduleimpl_id, - text=f"""Chargement notes dans { + text=f"""Notes dans { evaluation.moduleimpl.module.titre or evaluation.moduleimpl.module.code}""", url=status_url, max_frequency=30 * 60, # 30 minutes diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index b844a9d4..171af7e3 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -1,4 +1,4 @@ -/* ScoDoc, (c) Emmanuel Viennet 1998 - 2023 +/* ScoDoc, (c) Emmanuel Viennet 1998 - 2024 */ :root { @@ -40,6 +40,10 @@ h3 { font-weight: bold; } +body a { + color: rgb(4, 16, 159); +} + details>summary:first-of-type { display: list-item !important; } diff --git a/app/static/css/scodoc97.css b/app/static/css/scodoc97.css new file mode 100644 index 00000000..c97b98db --- /dev/null +++ b/app/static/css/scodoc97.css @@ -0,0 +1,207 @@ +/* ScoDoc, (c) Emmanuel Viennet 1998 - 2024 + */ +.scodoc-container { + display: grid; + grid-template-columns: 130px 1fr; + grid-template-rows: auto 1fr; +} + +.app-corner { + /* background-color: rgb(235, 235, 228); */ + grid-column-start: 1; + grid-row-start: 1; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.formsemestre-page-header { + grid-column-start: 2; + grid-row-start: 1; + display: flex; + flex-direction: column; + flex-grow: 1; + justify-content: left; + white-space: nowrap; + padding: 0 10px; + /* Optional: Padding for some space around the text */ +} + +#sidebar { + border-right: 1px solid rgb(230, 230, 225); + grid-column-start: 1; + grid-row-start: 2; + padding-left: 4px; + /* Sidebar transition */ + transition: transform 400ms ease, opacity 400ms ease; +} + +#app-content { + grid-column-start: 2; + grid-row-start: 2; + background-color: #f0f0f0; + /* Optional: background color for content area */ + /* Sidebar transition */ + transition: margin-left 400ms ease; +} + +.infos { + /* container infos semestre */ + font-size: 12pt; +} + +.sco_menu { + /* container menu bar semestre */ + background-color: lightblue; + flex-grow: 1; + padding: 5px; + margin-top: 5px; +} + +.hamburger { + white-space: nowrap; + display: flex; + align-items: center; +} + +.hamburger>div { + font-size: 12pt; + font-weight: bold; + vertical-align: bottom; + white-space: nowrap; +} + +.hamburger>.hamburger-icon { + font-size: 24pt; + margin-top: -8px; + margin-right: 8px; +} + +.app-corner .scodoc-index, +.app-corner .scodoc-index a { + font-size: 14pt; + display: inline; + color: rgb(4, 16, 159); +} + +.hamburger-menu { + display: none; + flex-direction: column; + background-color: #333; + position: fixed; + top: 50px; + left: 0; + /* width: 100%; */ + max-width: 400px; + z-index: 1001; + /* Ensure it is above the top bar */ +} + +.hamburger-menu div { + padding: 10px; + border-bottom: 1px solid #444; +} + +.hamburger-menu a { + color: white; + text-decoration: none; +} + +#toggle-sidebar-img { + box-sizing: content-box; + padding-left: 4px; + padding-right: 4px; + transition: transform 400ms ease; +} + +#toggle-sidebar-img.collapsed { + transform: scaleX(-1); +} + +.vspace48 { + margin-top: 48px; +} + +.hidden { + display: none; +} + +.overlay { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.05); + z-index: 1000; + /* Below the menu but above the top bar */ +} + +/* Media query for desktop devices */ +@media (min-width: 769px) { + #sidebar.collapsed { + /* Slide the sidebar out to the left */ + transform: translateX(-130px); + opacity: 0; + /* fade out effect */ + } + + #app-content.collapsed { + grid-column-start: 1; + grid-column-end: 3; + } +} + +/* Hide the sidebar for mobile devices and print */ +@media screen and (max-width: 768px), +print { + + #sidebar, + div.toggle-sidebar { + display: none; + } + + #app-content { + grid-column-start: 1; + grid-column-end: 3; + } +} + +/* Sidebar */ +#sidebar sco-title { + color: rgb(102, 102, 102); + font-size: large; + font-weight: bold; + text-decoration: none; +} + +#sidebar h2 { + color: rgb(102, 102, 102); + font-weight: bold; + font-size: large; + margin-bottom: 0; +} + +#sidebar div.sidebar-item { + margin-left: 4px; +} + +#sidebar div.sidebar-item a:link, +#sidebar div.sidebar-item a:link, +#sidebar div.sidebar-item a:visited { + color: rgb(4, 16, 159); + text-decoration: none; +} + +#sidebar div.sidebar-item a:hover { + color: rgb(153, 51, 51); + text-decoration: underline; +} + +/* Content */ +#app-content>.gtrcontent { + height: 100%; + margin-left: 10px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/app/static/icons/back.svg b/app/static/icons/back.svg new file mode 100644 index 00000000..67597351 --- /dev/null +++ b/app/static/icons/back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/templates/hamburger_menu.j2 b/app/templates/hamburger_menu.j2 new file mode 100644 index 00000000..654edefb --- /dev/null +++ b/app/templates/hamburger_menu.j2 @@ -0,0 +1,5 @@ +
+ Accueil général +
+
Item 2
+
Item 3
diff --git a/app/templates/sco_page.j2 b/app/templates/sco_page.j2 index 20229d90..43bf75fc 100644 --- a/app/templates/sco_page.j2 +++ b/app/templates/sco_page.j2 @@ -8,6 +8,7 @@ + @@ -21,25 +22,49 @@ {% endblock %} {% block content %} - - {% block scodoc_sidebar %} - {% include "sidebar.j2" %} - {% endblock %} + +
+
+ {% block hamburger_menu %} + {% include "hamburger_menu.j2" %} + {% endblock %} +
+
+
+
+
+ +
+
+ toggle sidebar +
+
+
+ {% include "flashed_messages.j2" %} + {% if sco.formsemestre %} + {% block formsemestre_header %} + {% include "formsemestre_header.j2" %} + {% endblock %} + {% endif %} +
+ -
- {% include "flashed_messages.j2" %} - {% if sco.formsemestre %} - {% block formsemestre_header %} - {% include "formsemestre_header.j2" %} - {% endblock %} - {% endif %} - -
- {% block app_content %} - {{ content | safe }} - {% endblock %} +
+
+
+ {% block app_content %} + {{ content | safe }} + {% endblock %} +
+
+ {% endblock %} {% block scripts %} @@ -58,6 +83,32 @@ } }; const SCO_URL = "{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}"; + function toggleSidebar() { + document.getElementById('sidebar').classList.toggle('collapsed'); + document.getElementById('app-content').classList.toggle('collapsed'); + document.getElementById('toggle-sidebar-img').classList.toggle('collapsed'); + } + + function toggleMobileMenu() { + const menu = document.getElementById('hamburgerMenu'); + const overlay = document.getElementById('overlay'); + if (menu.style.display === 'none' || menu.style.display === '') { + menu.style.display = 'flex'; + overlay.style.display = 'block'; + } else { + menu.style.display = 'none'; + overlay.style.display = 'none'; + } + } + + function closeMobileMenu() { + document.getElementById('hamburgerMenu').style.display = 'none'; + document.getElementById('overlay').style.display = 'none'; + } + + // Ensure the hamburger menu and overlay are hidden initially + document.getElementById('hamburgerMenu').style.display = 'none'; + document.getElementById('overlay').style.display = 'none'; {% endblock %} diff --git a/app/templates/sco_page_dept.j2 b/app/templates/sco_page_dept.j2 new file mode 100644 index 00000000..84a2293f --- /dev/null +++ b/app/templates/sco_page_dept.j2 @@ -0,0 +1,12 @@ +{%- extends 'sco_page.j2' -%} +{# -*- Base des pages dans département mais hors formsemestre -*- #} +{# -*- Comme sco_page mais cache le bandeau formsemestre -*- #} + +{% block styles %} +{{super()}} + +{% endblock %} diff --git a/app/templates/scolar/index.j2 b/app/templates/scolar/index.j2 index 2c3584a5..f82acbb9 100644 --- a/app/templates/scolar/index.j2 +++ b/app/templates/scolar/index.j2 @@ -1,6 +1,6 @@ {# page accueil département #} -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% block app_content %} + + `; + + this.exportFormat = null; + this.observer = new MutationObserver(() => this.render()); + + this.toggleDropdown = this.toggleDropdown.bind(this); + this.handleDocumentClick = this.handleDocumentClick.bind(this); + + this._internals = this.attachInternals(); + this._internals.setFormValue([]); + } + + connectedCallback() { + this.render(); + this.observer.observe(this, { childList: true, subtree: true }); + const btn = this.shadowRoot.querySelector(".dropdown-button"); + btn.addEventListener("click", this.toggleDropdown); + document.addEventListener("click", this.handleDocumentClick); + + this._updateSelect(); + } + + disconnectedCallback() { + this.observer.disconnect(); + document.removeEventListener("click", this.handleDocumentClick); + } + + toggleDropdown(event) { + event.stopPropagation(); + const dropdownContent = this.shadowRoot.querySelector(".dropdown-content"); + dropdownContent.style.display = + dropdownContent.style.display === "block" ? "none" : "block"; + } + + handleDocumentClick(event) { + if (!this.contains(event.target)) { + this.shadowRoot.querySelector(".dropdown-content").style.display = "none"; + } + } + + render() { + const container = this.shadowRoot.querySelector(".multi-select-container"); + container.innerHTML = ""; + + const optgroups = this.querySelectorAll("optgroup"); + + optgroups.forEach((optgroup) => { + const groupDiv = document.createElement("div"); + groupDiv.className = "optgroup"; + + const groupLabel = document.createElement("div"); + groupLabel.textContent = optgroup.label; + groupDiv.appendChild(groupLabel); + + const options = optgroup.querySelectorAll("option"); + options.forEach((option) => { + const optionDiv = document.createElement("label"); + optionDiv.className = "option"; + + const checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.value = option.value; + checkbox.name = this.getAttribute("name"); + if (option.hasAttribute("selected")) { + checkbox.checked = true; + optionDiv.classList.add("selected"); + } + checkbox.addEventListener("change", () => { + this.handleCheckboxChange(checkbox); + }); + + optionDiv.appendChild(checkbox); + optionDiv.appendChild(document.createTextNode(option.textContent)); + groupDiv.appendChild(optionDiv); + }); + + container.appendChild(groupDiv); + }); + + this._updateSelect(); + } + + handleCheckboxChange(checkbox) { + const opt = this.querySelector(`option[value="${checkbox.value}"]`); + const isSingle = opt.hasAttribute("single"); + if (!checkbox.checked) { + checkbox.parentElement.classList.remove("selected"); + } else { + checkbox.parentElement.classList.add("selected"); + // Gestion de l'option "single" + if (isSingle) { + // Uncheck all other checkboxes + const checkboxes = this.shadowRoot.querySelectorAll( + 'input[type="checkbox"]' + ); + checkboxes.forEach((cb) => { + if (cb !== checkbox) { + cb.checked = false; + cb.parentElement.classList.remove("selected"); + } + }); + } else { + // Uncheck the single checkbox if present + const singleCheckbox = Array.from( + this.shadowRoot.querySelectorAll('input[type="checkbox"]') + ).find((cb) => + this.querySelector(`option[value="${cb.value}"]`).hasAttribute( + "single" + ) + ); + if (singleCheckbox) { + singleCheckbox.checked = false; + singleCheckbox.parentElement.classList.remove("selected"); + } + } + } + this._updateSelect(); + } + + _updateSelect() { + const checkboxes = this.shadowRoot.querySelectorAll( + 'input[type="checkbox"]' + ); + const checkedBoxes = Array.from(checkboxes).filter( + (checkbox) => checkbox.checked + ); + + const values = checkedBoxes.map((checkbox) => checkbox.value); + + const opts = checkedBoxes.map((checkbox) => { + return this.querySelector(`option[value="${checkbox.value}"]`); + }); + + const btn = this.shadowRoot.querySelector(".dropdown-button"); + + if (checkedBoxes.length === 0) { + btn.textContent = this.label || "Select options"; + } else if (checkedBoxes.length < 4) { + btn.textContent = opts.map((opt) => opt.textContent).join(", ") + ""; + } else { + btn.textContent = `${checkedBoxes.length} sélections`; + } + + btn.textContent += " ⮛"; + + this._values(values); + + this.dispatchEvent(new Event("change")); + } + + _values(newValues = null) { + const checkboxes = this.shadowRoot.querySelectorAll( + 'input[type="checkbox"]' + ); + if (newValues === null) { + // Get selected values + const values = Array.from(checkboxes) + .filter((checkbox) => checkbox.checked) + .map((checkbox) => checkbox.value); + if (this.exportFormat) { + return this.exportFormat(values); + } + return values; + } else { + // Set selected values + checkboxes.forEach((checkbox) => { + checkbox.checked = newValues.includes(checkbox.value); + }); + + this._internals.setFormValue(this._values()); + } + } + + get value() { + return this._values(); + } + + set value(values) { + this._values(values); + } + + on(callback) { + this.addEventListener("change", callback); + } + + format(callback) { + this.exportFormat = callback; + } +} + +customElements.define("multi-select", MultiSelect); diff --git a/app/templates/assiduites/pages/signal_assiduites_group.j2 b/app/templates/assiduites/pages/signal_assiduites_group.j2 index fddae39c..b939944a 100644 --- a/app/templates/assiduites/pages/signal_assiduites_group.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_group.j2 @@ -7,7 +7,6 @@ {% block scripts %} {{ super() }} - @@ -73,9 +72,10 @@ creerTousLesEtudiants(etuds); }); - $("#group_ids_sel").on("change", ()=>{ + const group_sel = document.querySelector("#group_ids_sel") + group_sel.on((values)=>{ main(); - }) + }); const moduleimpls = {}; const inscriptionsModules = new Map(); @@ -83,7 +83,8 @@ async function main(){ dateCouranteEstTravaillee(); - etuds = await recupEtuds($('#group_ids_sel').val()); + let group_ids = group_sel.value; + etuds = await recupEtuds(group_ids); if (etuds.size != 0){ await recupAssiduites(etuds, $("#date").datepicker("getDate")); } @@ -101,8 +102,7 @@ {% block styles %} {{ super() }} - - +{# #} @@ -153,12 +153,12 @@
Groupes : {{grp|safe}}
-
-
@@ -166,8 +166,8 @@
{{timeline|safe}}
- - + +
diff --git a/app/templates/babase.j2 b/app/templates/babase.j2 index 2dc3aa89..94baa48d 100644 --- a/app/templates/babase.j2 +++ b/app/templates/babase.j2 @@ -33,6 +33,7 @@ + diff --git a/app/views/assiduites.py b/app/views/assiduites.py index 10e092cb..c1d210ab 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -94,7 +94,7 @@ from app.tables.visu_assiduites import TableAssi, etuds_sorted_from_ids from app.scodoc.sco_archives_justificatifs import JustificatifArchiver -CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS +CSSSTYLES = html_sco_header.BOOTSTRAP_CSS # -------------------------------------------------------------------- @@ -1164,7 +1164,7 @@ def signal_assiduites_group(): formsemestre_date_fin=str(formsemestre.date_fin), formsemestre_id=formsemestre_id, gr_tit=gr_tit, - grp=sco_groups_view.menu_groups_choice(groups_infos), + grp=sco_groups_view.menu_groups_choice(groups_infos, html_export=False), minitimeline=_mini_timeline(), moduleimpl_select=_module_selector(formsemestre, moduleimpl_id), nonworkdays=_non_work_days(), diff --git a/app/views/groups.py b/app/views/groups.py index ae6bca0e..4f8e815d 100644 --- a/app/views/groups.py +++ b/app/views/groups.py @@ -45,7 +45,7 @@ def formulaire_feuille_appel(): formsemestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id) - group_ids: list[int] = request.args.get("group_ids", "").split(",") + group_ids: list[int] = request.args.getlist("group_ids") form: groups_form.FeuilleAppelPreForm = groups_form.FeuilleAppelPreForm( request.form @@ -65,7 +65,7 @@ def formulaire_feuille_appel(): "ens": form.ens.data or "", } - form_group_ids: list[str] = request.form.getlist("group_ids") + form_group_ids: list[str] = request.form.get("group_ids", "").split(",") if form_group_ids: groups_infos = DisplayedGroupsInfos( form_group_ids, @@ -89,5 +89,5 @@ def formulaire_feuille_appel(): sco_data=ScoData(formsemestre=formsemestre), form=form, group_name=groups_infos.groups_titles, - grp=menu_groups_choice(groups_infos), + grp=menu_groups_choice(groups_infos, html_export=False), ) From 5b68adaf872ee672c4f6f956147ae611d5ab6b29 Mon Sep 17 00:00:00 2001 From: Iziram Date: Wed, 31 Jul 2024 16:08:21 +0200 Subject: [PATCH 13/55] =?UTF-8?q?multiselect.py=20+=20fix=20bug=20event=20?= =?UTF-8?q?+=20changement=20ic=C3=B4ne=20+=20unfixed=20height?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/forms/multiselect.py | 118 ++++++++++++++++++++++++++++++++++ app/scodoc/sco_groups_view.py | 2 +- app/scodoc/sco_utils.py | 117 +-------------------------------- app/static/js/multi-select.js | 22 ++++--- 4 files changed, 135 insertions(+), 124 deletions(-) create mode 100644 app/forms/multiselect.py diff --git a/app/forms/multiselect.py b/app/forms/multiselect.py new file mode 100644 index 00000000..77b13626 --- /dev/null +++ b/app/forms/multiselect.py @@ -0,0 +1,118 @@ +""" +Simplification des multiselect HTML/JS +""" + + +class MultiSelect: + """ + Classe pour faciliter l'utilisation du multi-select HTML/JS + + Les values sont représentées en dict { + value: "...", + label:"...", + selected: True/False (default to False), + single: True/False (default to False) + } + + Args: + values (dict[str, list[dict]]): Dictionnaire des valeurs + génère des pour chaque clef du dictionnaire + génère des
""" ) diff --git a/app/scodoc/sco_formations.py b/app/scodoc/sco_formations.py index 2ac67a98..b05a1b2f 100644 --- a/app/scodoc/sco_formations.py +++ b/app/scodoc/sco_formations.py @@ -657,7 +657,7 @@ def formation_list_table(detail: bool) -> GenTable: "version": "Version", "formation_code": "Code", "sems_list_txt": "Semestres", - "referentiel": "Réf.", + "referentiel": "Réf. Comp.", "date_fin_dernier_sem": "Fin dernier sem.", "annee_dernier_sem": "Année dernier sem.", "semestres_ues": "Semestres avec UEs", diff --git a/app/scodoc/sco_users.py b/app/scodoc/sco_users.py index 90d1688e..c1399dd5 100644 --- a/app/scodoc/sco_users.py +++ b/app/scodoc/sco_users.py @@ -54,7 +54,7 @@ def index_html( all_depts = int(all_depts) with_inactives = int(with_inactives) - H = ["

Gestion des utilisateurs

"] + H = ["

Gestion des utilisateurs

"] if current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept): H.append( @@ -127,7 +127,7 @@ def index_html( H.append(content) return render_template( - "sco_page.j2", content="\n".join(H), title="Gestion des utilisateurs" + "sco_page_dept.j2", content="\n".join(H), title="Gestion des utilisateurs" ) diff --git a/app/static/css/scodoc97.css b/app/static/css/scodoc97.css index 38bfe85b..0e5f1ac5 100644 --- a/app/static/css/scodoc97.css +++ b/app/static/css/scodoc97.css @@ -13,6 +13,7 @@ display: flex; flex-direction: column; justify-content: space-between; + padding-left: 4px; } .formsemestre-page-header { @@ -78,15 +79,25 @@ margin-right: 8px; } -.app-corner .scodoc-index, -.app-corner .scodoc-index a { +.scodoc-index, +.scodoc-index a { font-size: 14pt; display: flex; color: rgb(4, 16, 159); - justify-content: center; width: 100%; } +div.scodoc-index[mobile="true"] a { + justify-content: center; +} + +.scodoc-index a:any-link { + text-decoration: none; +} + +.scodoc-index.collapsed { + display: none; +} .hamburger-menu { display: none; @@ -210,20 +221,24 @@ print { text-decoration: none; } -#sidebar h2 { +#sidebar .sidebar-link-dept { color: rgb(102, 102, 102); font-weight: bold; font-size: large; margin-bottom: 0; + margin-top: 12px; } +#sidebar .sidebar-link-dept a:any-link { + text-decoration: none; +} + + #sidebar div.sidebar-item { margin-left: 4px; } -#sidebar div.sidebar-item a:link, -#sidebar div.sidebar-item a:link, -#sidebar div.sidebar-item a:visited { +#sidebar div.sidebar-item a:any-link { color: rgb(4, 16, 159); text-decoration: none; } diff --git a/app/templates/assiduites/pages/bilan_dept.j2 b/app/templates/assiduites/pages/bilan_dept.j2 index 1407067c..6c180cea 100644 --- a/app/templates/assiduites/pages/bilan_dept.j2 +++ b/app/templates/assiduites/pages/bilan_dept.j2 @@ -1,4 +1,4 @@ -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% block styles %} {{super()}} diff --git a/app/templates/dept_news.j2 b/app/templates/dept_news.j2 index 23b0ae51..5e132bc7 100644 --- a/app/templates/dept_news.j2 +++ b/app/templates/dept_news.j2 @@ -1,5 +1,5 @@ {# -*- mode: jinja-html -*- #} -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% block styles %} {{super()}} {% endblock %} diff --git a/app/templates/sco_page.j2 b/app/templates/sco_page.j2 index 43d73a6a..75abae69 100644 --- a/app/templates/sco_page.j2 +++ b/app/templates/sco_page.j2 @@ -100,6 +100,9 @@ document.getElementById('sidebar').classList.toggle('collapsed'); document.getElementById('app-content').classList.toggle('collapsed'); document.getElementById('toggle-sidebar-img').classList.toggle('collapsed'); + document.querySelectorAll('.scodoc-index').forEach(element => { + element.classList.toggle('collapsed'); + }); } diff --git a/app/templates/sco_page_dept.j2 b/app/templates/sco_page_dept.j2 index 84a2293f..3dec68ea 100644 --- a/app/templates/sco_page_dept.j2 +++ b/app/templates/sco_page_dept.j2 @@ -8,5 +8,21 @@ .formsemestre-page-header { display: none; } + +div.scodoc-container > div#app-content { + grid-row-start: 1; + grid-row-end: span 2; +} + +@media (min-width: 769px) { + /* On desktop, we need to adjust the margin to make room for the button << */ + div.scodoc-container > div#app-content.collapsed { + margin-left: 16px; + } + div.scodoc-container > div#app-content { + margin-top: 8px; + } +} + {% endblock %} diff --git a/app/templates/sidebar.j2 b/app/templates/sidebar.j2 index 5621ca4e..eecc6924 100755 --- a/app/templates/sidebar.j2 +++ b/app/templates/sidebar.j2 @@ -2,9 +2,9 @@ {# -*- mode: jinja-html -*- #} {# sidebar_common #} -

+
ScoDoc -

+
Dépt. {{ sco.prefs["DeptName"] }} + {% if sco.prefs["DeptIntranetURL"] %} {% endif %} + + {# /sidebar_common #}
Chercher étudiant: @@ -138,7 +144,7 @@ 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) { diff --git a/app/views/notes.py b/app/views/notes.py index 3d8746a1..e97bfcdf 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -676,7 +676,7 @@ def index_html(): return table.make_page(fmt=fmt, filename=f"Formations-{g.scodoc_dept}") H = [ - f"""

Formations (programmes pédagogiques)

+ f"""

Formations (programmes pédagogiques)