fix(teams): eliminate double scrollbar and white void in planning, highlight week/month scope controls

This commit is contained in:
kdeterme 2026-09-19 14:42:13 +02:00
parent 74c1bf2447
commit 6e4a304930

View file

@ -138,29 +138,79 @@
} }
/* --- Onglet 2 : Planification / Calendrier des équipes --- */ /* --- Onglet 2 : Planification / Calendrier des équipes --- */
body.tab-planning-active #content-wrapper,
#content-wrapper:has(#tab-planning.active) {
overflow-y: hidden !important;
padding-bottom: 2px !important;
}
.teams-container {
display: flex;
flex-direction: column;
height: 100%;
max-height: calc(100vh - 65px);
overflow: hidden;
}
.teams-header-row {
flex-shrink: 0;
margin-bottom: 6px !important;
}
#teamsTabContent {
flex: 1 1 auto;
min-height: 0;
display: flex;
flex-direction: column;
}
.tab-pane.active {
flex: 1 1 auto;
min-height: 0;
display: flex;
flex-direction: column;
}
#tab-current-state.active {
overflow-y: auto;
display: block;
}
#tab-planning.active {
display: flex;
flex-direction: column;
overflow: hidden;
flex: 1 1 auto;
min-height: 0;
}
.planning-toolbar { .planning-toolbar {
flex-shrink: 0;
background: #ffffff; background: #ffffff;
border: 1px solid #dee2e6; border: 1px solid #dee2e6;
border-radius: 8px; border-radius: 8px;
padding: 10px 14px; padding: 8px 12px;
margin-bottom: 16px; margin-bottom: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.04); box-shadow: 0 1px 3px rgba(0,0,0,0.04);
} }
.planning-layout { .planning-layout {
flex: 1 1 auto;
min-height: 0;
display: flex; display: flex;
gap: 16px; gap: 12px;
align-items: flex-start; align-items: stretch;
overflow: hidden;
} }
.planning-matrix-wrapper { .planning-matrix-wrapper {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 0; min-width: 0;
height: 100%;
background: #ffffff; background: #ffffff;
border: 1px solid #dee2e6; border: 1px solid #dee2e6;
border-radius: 8px; border-radius: 8px;
overflow: auto; overflow: auto;
max-height: calc(100vh - 170px);
box-shadow: 0 2px 6px rgba(0,0,0,0.04); box-shadow: 0 2px 6px rgba(0,0,0,0.04);
position: relative; position: relative;
} }
@ -168,19 +218,19 @@
.planning-sidebar-wrapper { .planning-sidebar-wrapper {
width: 300px; width: 300px;
flex: 0 0 300px; flex: 0 0 300px;
height: 100%;
background: #ffffff; background: #ffffff;
border: 1px solid #dee2e6; border: 1px solid #dee2e6;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.04); box-shadow: 0 2px 6px rgba(0,0,0,0.04);
position: sticky;
top: 20px;
max-height: calc(100vh - 170px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
} }
.planning-sidebar-header { .planning-sidebar-header {
padding: 12px 14px; flex-shrink: 0;
padding: 10px 12px;
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid #f0f0f0;
background: #fdfdfd; background: #fdfdfd;
border-top-left-radius: 8px; border-top-left-radius: 8px;
@ -188,9 +238,10 @@
} }
.planning-sidebar-body { .planning-sidebar-body {
padding: 10px 14px;
overflow-y: auto;
flex: 1 1 auto; flex: 1 1 auto;
min-height: 0;
padding: 8px 12px;
overflow-y: auto;
} }
/* Table planning */ /* Table planning */
@ -446,10 +497,10 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container-fluid py-3"> <div class="container-fluid px-3 pt-2 pb-0 teams-container">
<!-- En-tête avec titre & onglets --> <!-- En-tête avec titre & onglets -->
<div class="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2"> <div class="d-flex justify-content-between align-items-center mb-2 flex-wrap gap-2 teams-header-row">
<div> <div>
<h4 class="mb-0"> <h4 class="mb-0">
<i class="bi bi-people-fill me-2 text-primary"></i>{% trans "Gestion des équipes" %} <i class="bi bi-people-fill me-2 text-primary"></i>{% trans "Gestion des équipes" %}
@ -672,16 +723,19 @@
</div> </div>
<!-- Sélecteur de mode de vue --> <!-- Sélecteur de mode de vue -->
<div class="btn-group btn-group-sm" role="group" id="planning-viewmode-group"> <div class="d-flex align-items-center gap-1">
<button type="button" class="btn btn-outline-primary" data-mode="work_week">{% trans "5j (Ouvré)" %}</button> <span class="text-muted small text-nowrap"><i class="bi bi-eye me-1"></i>{% trans "Vue :" %}</span>
<button type="button" class="btn btn-primary" data-mode="week">{% trans "1 Semaine (7j)" %}</button> <div class="btn-group btn-group-sm" role="group" id="planning-viewmode-group">
<button type="button" class="btn btn-outline-primary" data-mode="two_weeks">{% trans "2 Semaines" %}</button> <button type="button" class="btn btn-outline-primary" data-mode="work_week">{% trans "5j (Ouvré)" %}</button>
<button type="button" class="btn btn-outline-primary" data-mode="month">{% trans "1 Mois" %}</button> <button type="button" class="btn btn-primary" data-mode="week">{% trans "1 Semaine (7j)" %}</button>
<button type="button" class="btn btn-outline-primary" data-mode="two_weeks">{% trans "2 Semaines" %}</button>
<button type="button" class="btn btn-outline-primary" data-mode="month">{% trans "1 Mois" %}</button>
</div>
</div> </div>
<!-- Sélecteur global de portée d'assignation --> <!-- Sélecteur global de portée d'assignation -->
<div class="d-flex align-items-center gap-1 ms-1"> <div class="d-flex align-items-center gap-1 ms-1 p-1 px-2 rounded" style="background: #eef2ff; border: 1px solid #c7d2fe;">
<span class="text-muted small text-nowrap"><i class="bi bi-clock-history me-1"></i>{% trans "Portée :" %}</span> <span class="fw-semibold small text-primary-emphasis text-nowrap" title="{% trans "Période sur laquelle un membre est affecté ou retiré lors d'un glisser-déposer" %}"><i class="bi bi-calendar-check me-1 text-primary"></i>{% trans "Affecter par :" %}</span>
<div class="btn-group btn-group-sm" role="group" id="planning-assign-scope-group" title="{% trans "Durée appliquée lors de l'assignation ou du retrait d'un membre" %}"> <div class="btn-group btn-group-sm" role="group" id="planning-assign-scope-group" title="{% trans "Durée appliquée lors de l'assignation ou du retrait d'un membre" %}">
<button type="button" class="btn btn-primary" data-scope="day">{% trans "Jour" %}</button> <button type="button" class="btn btn-primary" data-scope="day">{% trans "Jour" %}</button>
<button type="button" class="btn btn-outline-primary" data-scope="week">{% trans "Semaine" %}</button> <button type="button" class="btn btn-outline-primary" data-scope="week">{% trans "Semaine" %}</button>
@ -841,6 +895,9 @@
{% trans "Vous tentez de l'assigner à l'équipe" %} : <strong id="multiTeamTargetTeamName"></strong>. {% trans "Vous tentez de l'assigner à l'équipe" %} : <strong id="multiTeamTargetTeamName"></strong>.
{% trans "Souhaitez-vous déplacer ce membre ou l'affecter aux deux équipes ?" %} {% trans "Souhaitez-vous déplacer ce membre ou l'affecter aux deux équipes ?" %}
</p> </p>
<div class="mt-2 p-2 bg-light rounded small border">
<i class="bi bi-clock-history me-1 text-primary"></i>{% trans "Portée d'affectation :" %} <strong id="multiTeamScopeDisplay">Jour</strong>
</div>
</div> </div>
<div class="modal-footer border-top-0 pt-0 d-flex justify-content-between"> <div class="modal-footer border-top-0 pt-0 d-flex justify-content-between">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal"> <button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">
@ -1594,7 +1651,7 @@ const initialDate = (function() {
const initialViewMode = (function() { const initialViewMode = (function() {
const saved = getStoredSetting('view_mode', 'week'); const saved = getStoredSetting('view_mode', 'week');
if (['work_week', 'week', 'two_weeks'].includes(saved)) return saved; if (['work_week', 'week', 'two_weeks', 'month'].includes(saved)) return saved;
return 'week'; return 'week';
})(); })();
@ -1693,17 +1750,24 @@ document.addEventListener('DOMContentLoaded', function() {
filterSidebarMembers(); filterSidebarMembers();
}); });
// Mémorisation de l'onglet actif // Gestion du basculement d'onglets
$('.teams-nav-tabs .nav-link').on('shown.bs.tab', function(e) { function updatePlanningTabClass() {
const activeTabId = $(e.target).attr('id'); if ($('#tab-planning-btn').hasClass('active')) {
setStoredSetting('active_tab', activeTabId); $('body').addClass('tab-planning-active');
}); } else {
$('body').removeClass('tab-planning-active');
}
}
// Chargement automatique lors de l'accès à l'onglet Planification
let planningLoadedOnce = false; let planningLoadedOnce = false;
$('#tab-planning-btn').on('shown.bs.tab', function() { $('button[data-bs-toggle="pill"]').on('shown.bs.tab', function(e) {
if (!planningLoadedOnce) { const tabId = $(e.target).attr('id');
planningLoadedOnce = true; setStoredSetting('active_tab', tabId);
updatePlanningTabClass();
if (tabId === 'tab-planning-btn') {
if (!planningLoadedOnce) {
planningLoadedOnce = true;
}
loadPlanningData(); loadPlanningData();
} }
}); });
@ -1716,6 +1780,7 @@ document.addEventListener('DOMContentLoaded', function() {
bootstrap.Tab.getOrCreateInstance(tabEl).show(); bootstrap.Tab.getOrCreateInstance(tabEl).show();
} }
} }
updatePlanningTabClass();
// Mode duplication modal switch // Mode duplication modal switch
$('input[name="dupMode"]').on('change', function() { $('input[name="dupMode"]').on('change', function() {
@ -2117,6 +2182,11 @@ function initPlanningDragAndDrop() {
targetDate: targetDate targetDate: targetDate
}; };
let scopeLabel = "{% trans 'Jour'|escapejs %}";
if (_planningState.assignScope === 'week') scopeLabel = "{% trans 'Semaine complète'|escapejs %}";
if (_planningState.assignScope === 'month') scopeLabel = "{% trans 'Mois complet'|escapejs %}";
$('#multiTeamScopeDisplay').text(scopeLabel);
const modalEl = document.getElementById('planningMultiTeamConfirmModal'); const modalEl = document.getElementById('planningMultiTeamConfirmModal');
const modal = new bootstrap.Modal(modalEl); const modal = new bootstrap.Modal(modalEl);
modal.show(); modal.show();