From fb62904cc9db2271b5628021e860ce0bbff30da4 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 5 Jan 2024 14:10:12 +0100 Subject: [PATCH] EDT: front: navigation et dates --- app/static/css/edt.css | 61 ++++++++++++++- app/templates/formsemestre/edt.j2 | 122 +++++++++++++++++++++++++++--- app/views/notes_formsemestre.py | 2 + 3 files changed, 173 insertions(+), 12 deletions(-) diff --git a/app/static/css/edt.css b/app/static/css/edt.css index 1564596d1..86ad9f4c0 100644 --- a/app/static/css/edt.css +++ b/app/static/css/edt.css @@ -1,8 +1,67 @@ -#show_modules_titles_form { +#calendar_control_form { display: inline-block; margin-left: 16px; } +/* Style for the dropdown button */ +.dropdown { + position: relative; + display: inline-block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.dropbtn { + background-color: rgb(233,233,233); + color: black; + padding: 2px 32px 2px 4px; + margin-left: 16px; + font-size: 16px; + border: 1px solid black; + border-radius: 5px; /* Rounded corners */ + cursor: pointer; + /* Add arrow to the button */ + background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2212%22%20height%3D%227%22%20viewBox%3D%220%200%2012%207%22%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cpath%20d%3D%22M1%201L6%206L11%201%22%20stroke%3D%22black%22%20stroke-width%3D%222%22/%3E%3C/svg%3E'); + background-repeat: no-repeat; + background-position: right 10px center; +} + +/* Dropdown content (hidden by default) */ +.dropdown-content { + display: none; + position: absolute; + background-color: #f9f9f9; + min-width: 210px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; + border-radius: 5px; /* Rounded corners */ + overflow: hidden; /* Ensures rounded corners for dropdown items */ +} + +/* Style for the dropdown items */ +.dropdown-content ul { + list-style: none; + padding: 0; + margin: 0; +} + +.dropdown-content ul li { + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; +} + +.dropdown-content ul li a { + color: black; + text-decoration: none; + display: block; +} + +.dropdown-content ul li label { + cursor: pointer; + display: block; +} + .toastui-calendar-template-time { padding: 4px; word-break: break-all; diff --git a/app/templates/formsemestre/edt.j2 b/app/templates/formsemestre/edt.j2 index 55dba3222..fab72f51b 100644 --- a/app/templates/formsemestre/edt.j2 +++ b/app/templates/formsemestre/edt.j2 @@ -16,11 +16,29 @@ {{ form_groups_choice|safe }} -
- noms complets des modules -
+ +
+ + + +
@@ -35,7 +53,7 @@
-
+
    @@ -73,10 +91,23 @@ function getDataAction(target) { return target.dataset ? target.dataset.action : target.getAttribute('data-action'); } +function getNextDayISODate(isoDate) { + // Parse the ISO date string into a Date object + const date = new Date(isoDate); + + // Add one day + date.setDate(date.getDate() + 1); + + // Convert back to ISO date string (YYYY-MM-DD) + return date.toISOString().split('T')[0]; +} + +var calendar; + document.addEventListener('DOMContentLoaded', function() { document.getElementById('menu-navi').addEventListener('click', onClickNavi); const Calendar = tui.Calendar; - const container = document.getElementById('calendar'); + const container = document.getElementById('formsemestre-calendar'); const options = { defaultView: 'week', calendars: [ @@ -118,7 +149,7 @@ document.addEventListener('DOMContentLoaded', function() { }, }; - const calendar = new Calendar(container, options); + calendar = new Calendar(container, options); fetch(`${SCO_URL}/../api/formsemestre/{{formsemestre.id}}/edt?{{groups_query_args|safe}}&show_modules_titles={{show_modules_titles}}`) .then(r=>{return r.json()}) @@ -131,6 +162,12 @@ document.addEventListener('DOMContentLoaded', function() { } }); + {% if current_date %} + // we need to add one day because our weeks are starting on Monday + calendar.setDate( getNextDayISODate("{{current_date}}") ); + {% endif %} + changeCalendarDate(); + function formatDate(date) { let year = date.getFullYear(); let month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are zero-indexed in JavaScript @@ -145,10 +182,17 @@ document.addEventListener('DOMContentLoaded', function() { var html = []; if (viewName === 'day') { - html.push(currentCalendarDate('YYYY.MM.DD')); + html.push(calendar.getDate().toDate().toLocaleString('fr-Fr', { + year: 'numeric', + month: 'long', + day: 'numeric'})); } else if (viewName === 'month' && (!options.month.visibleWeeksCount || options.month.visibleWeeksCount > 4)) { - html.push(currentCalendarDate('YYYY.MM')); + html.push( + calendar.getDate().toDate().toLocaleString('fr-Fr', { + year: 'numeric', + month: 'long', + })); } else { html.push(formatDate(calendar.getDateRangeStart())); html.push(' - '); @@ -173,9 +217,65 @@ document.addEventListener('DOMContentLoaded', function() { return; } - setRenderRangeText(); // setSchedules(); + changeCalendarDate(); } + // Update current URL when date change (newDate=ISO string) + function updateCurrentDateInUrl(newDate) { + // Parse the current URL + const currentUrl = new URL(window.location.href); + + // Access and modify the search parameters + const searchParams = currentUrl.searchParams; + searchParams.set('current_date', newDate); // Set the new date + + // Create the new URL + const newUrl = `${currentUrl.origin}${currentUrl.pathname}?${searchParams.toString()}`; + + // Update the URL without reloading the page + window.history.pushState({ path: newUrl }, '', newUrl); + } + // Update "current" date (URL and title) + function changeCalendarDate() { + setRenderRangeText(); + // current calendar date, ISO, without time + const iso_date = calendar.getDateRangeStart().toDate().toISOString().split('T')[0]; + updateCurrentDateInUrl(iso_date); + calendar_control_form.current_date = iso_date; + } + // View menu + const dropdown = document.querySelector('.dropdown'); + const dropbtn = document.querySelector('.dropbtn'); + const dropdownContent = document.querySelector('.dropdown-content'); + + dropbtn.addEventListener('click', function(event) { + dropdownContent.style.display = dropdownContent.style.display === 'block' ? 'none' : 'block'; + event.stopPropagation(); + }); + + document.querySelectorAll('.dropdown-content a').forEach(item => { + item.addEventListener('click', function(e) { + e.preventDefault(); + const selectedText = this.textContent; + const selectedView = this.getAttribute('data-view'); + calendar.changeView(selectedView); // Change the calendar view + dropbtn.textContent = selectedText; // Update the button text + dropdownContent.style.display = 'none'; + }); + }); + + const showModulesTitlesCheckbox = document.getElementById('showModulesTitles'); + showModulesTitlesCheckbox.addEventListener('change', function() { + calendar_control_form.show_modules_titles.value = (calendar_control_form.show_modules_titles.value=="1") ? "0" : "1"; + calendar_control_form.submit(); + }); + + // Close dropdown when clicking outside + window.addEventListener('click', function() { + if (dropdownContent.style.display === 'block') { + dropdownContent.style.display = 'none'; + } + }); }); diff --git a/app/views/notes_formsemestre.py b/app/views/notes_formsemestre.py index b683d0a22..678bbbf60 100644 --- a/app/views/notes_formsemestre.py +++ b/app/views/notes_formsemestre.py @@ -163,6 +163,7 @@ def formsemestre_edit_modimpls_codes(formsemestre_id: int): @permission_required(Permission.ScoView) def formsemestre_edt(formsemestre_id: int): """Expérimental: affiche emploi du temps du semestre""" + current_date = request.args.get("current_date") show_modules_titles = scu.to_bool(request.args.get("show_modules_titles", False)) formsemestre = FormSemestre.get_formsemestre(formsemestre_id) cfg = ScoDocSiteConfig.query.filter_by(name="assi_morning_time").first() @@ -177,6 +178,7 @@ def formsemestre_edt(formsemestre_id: int): ) return render_template( "formsemestre/edt.j2", + current_date=current_date, formsemestre=formsemestre, hour_start=hour_start, hour_end=hour_end,