From e271ea375e32ce79a03154c16b2387483912cdf5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Tue, 24 May 2022 16:53:02 +0200
Subject: [PATCH 1/2] manager: use sidetabs to navigate between agenda settings
 (#65653)

---
 chrono/manager/static/css/style.scss          |  11 +-
 .../chrono/manager_agenda_settings.html       | 132 ++++-----
 .../manager_events_agenda_settings.html       | 267 +++++++++---------
 .../manager_meetings_agenda_settings.html     | 248 ++++++++--------
 .../manager_virtual_agenda_settings.html      | 140 ++++-----
 tests/manager/test_all.py                     |   4 +-
 tests/manager/test_exception.py               |   2 +-
 7 files changed, 412 insertions(+), 392 deletions(-)

diff --git a/chrono/manager/static/css/style.scss b/chrono/manager/static/css/style.scss
index 0624a44c..46f207f0 100644
--- a/chrono/manager/static/css/style.scss
+++ b/chrono/manager/static/css/style.scss
@@ -58,8 +58,6 @@ h2 span.identifier {
 .timeperiods {
 	display: flex;
 	flex-wrap: wrap;
-	margin-right: -10px;
-	margin-bottom: -10px;
 }
 
 .timeperiods .timeperiod {
@@ -522,3 +520,12 @@ table.timesheet {
 .page_break {
 	height: 20px;
 }
+
+div.agenda-settings .pk-tabs--container {
+	& > div {
+		padding: 1ex;
+		.panel--buttons a.button {
+			line-height: inherit;
+		}
+	}
+}
diff --git a/chrono/manager/templates/chrono/manager_agenda_settings.html b/chrono/manager/templates/chrono/manager_agenda_settings.html
index 781e3ad8..c4d3d5e9 100644
--- a/chrono/manager/templates/chrono/manager_agenda_settings.html
+++ b/chrono/manager/templates/chrono/manager_agenda_settings.html
@@ -35,73 +35,77 @@
 
 {% block content %}
 
-{% block agenda-settings %}
-{% endblock %}
+<div class="section agenda-settings">
+<div class="pk-tabs">
+  <div class="pk-tabs--tab-list" role="tablist">
+    {% block agenda-settings-extra-tab-buttons %}{% endblock %}
+    {% if object.kind != 'virtual' %}
+    <button aria-controls="panel-reminders" aria-selected="false" id="tab-reminders" role="tab" tabindex="-1">{% trans "Booking reminders" %}</button>
+    {% endif %}
+    <button aria-controls="panel-delays" aria-selected="false" id="tab-delays" role="tab" tabindex="-1">{% trans "Booking Delays" %}</button>
+    <button aria-controls="panel-permissions" aria-selected="false" id="tab-permissions" role="tab" tabindex="-1">{% trans "Permissions" %}</button>
+  </div>
+  <div class="pk-tabs--container">
 
-{% block agenda-reminder %}
-<div class="section">
-<h3>{% trans "Booking reminders" %}
-<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-reminder-settings' pk=object.id %}">{% trans "Configure" %}</a>
-</h3>
-<div>
-{% for info in agenda.reminder_settings.display_info %}
-<p>{{ info }}</p>
-{% empty %}
-<p>{% trans "Reminders are disabled for this agenda." %}</p>
-{% endfor %}
-<p>
-{% if agenda.reminder_settings.days_before_email %}
-<a rel="popup" data-selector="#message-preview" href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='email' %}">{% trans "Preview email" %}</a>
-{% endif %}
-{% if agenda.reminder_settings.days_before_sms %}
-<a rel="popup" data-selector="#message-preview"  href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='sms' %}">{% trans "Preview SMS" %}</a>
-{% endif %}
-</p>
-{% if agenda.reminder_settings.days_before_email or agenda.reminder_settings.days_before_sms %}
-<p>
-<a rel="popup" href="{% url 'chrono-manager-agenda-reminder-test' pk=object.pk %}">{% trans "Test reminder sending" %}</a>
-</p>
-{% endif %}
-</div>
-</div>
-{% endblock %}
+    {% block agenda-settings-extra-tab-list %}{% endblock %}
 
-{% block agenda-permissions %}
-<div class="section">
-<h3>{% trans "Permissions" %}
-<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-roles' pk=object.id %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-<ul>
-  <li>{% trans "Edit Role:" %} {% if agenda.edit_role %}{{ agenda.edit_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
-  <li>{% trans "View Role:" %} {% if agenda.view_role %}{{ agenda.view_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
-</ul>
-</div>
-</div>
-{% endblock %}
-
-{% block agenda-booking-delays %}
-<div class="section">
-<h3>{% trans "Booking Delays" %}
-<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-delays' pk=object.id %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-<ul>
-  <li>{% trans "Minimal booking delay:" %}
-      {% if agenda.minimal_booking_delay is not None %}
-        {% if agenda.minimal_booking_delay_in_working_days %}
-        {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} working day{% plural %}{{ count }} working days{% endblocktrans %}
-        {% else %}
-        {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
+    {% if object.kind != 'virtual' %}
+    <div aria-labelledby="tab-reminders" id="panel-reminders" role="tabpanel" tabindex="0" hidden="">
+      {% for info in agenda.reminder_settings.display_info %}
+      <p>{{ info }}</p>
+      {% empty %}
+      <p>{% trans "Reminders are disabled for this agenda." %}</p>
+      {% endfor %}
+      <p>
+        {% if agenda.reminder_settings.days_before_email %}
+        <a rel="popup" data-selector="#message-preview" href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='email' %}">{% trans "Preview email" %}</a>
+        {% endif %}
+        {% if agenda.reminder_settings.days_before_sms %}
+        <a rel="popup" data-selector="#message-preview"  href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='sms' %}">{% trans "Preview SMS" %}</a>
         {% endif %}
-      {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
-  <li>{% trans "Maximal booking delay:" %}
-      {% if agenda.maximal_booking_delay is not None %}
-        {% blocktrans count count=agenda.maximal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
-      {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
-</ul>
+      </p>
+      {% if agenda.reminder_settings.days_before_email or agenda.reminder_settings.days_before_sms %}
+      <p>
+        <a rel="popup" href="{% url 'chrono-manager-agenda-reminder-test' pk=object.pk %}">{% trans "Test reminder sending" %}</a>
+      </p>
+      {% endif %}
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-reminder-settings' pk=object.id %}">{% trans "Configure" %}</a>
+      </div>
+    </div>
+    {% endif %}
+
+    <div aria-labelledby="tab-delays" hidden="" id="panel-delays" role="tabpanel" tabindex="0">
+      <ul>
+        <li>{% trans "Minimal booking delay:" %}
+            {% if agenda.minimal_booking_delay is not None %}
+              {% if agenda.minimal_booking_delay_in_working_days %}
+              {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} working day{% plural %}{{ count }} working days{% endblocktrans %}
+              {% else %}
+              {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
+              {% endif %}
+            {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
+        <li>{% trans "Maximal booking delay:" %}
+            {% if agenda.maximal_booking_delay is not None %}
+              {% blocktrans count count=agenda.maximal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
+            {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
+      </ul>
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-delays' pk=object.id %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
+
+    <div aria-labelledby="tab-permissions" hidden="" id="panel-permissions" role="tabpanel" tabindex="0">
+      <ul>
+        <li>{% trans "Edit Role:" %} {% if agenda.edit_role %}{{ agenda.edit_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
+        <li>{% trans "View Role:" %} {% if agenda.view_role %}{{ agenda.view_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
+      </ul>
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-roles' pk=object.id %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
+
+  </div>
 </div>
 </div>
 {% endblock %}
-
-{% endblock %}
diff --git a/chrono/manager/templates/chrono/manager_events_agenda_settings.html b/chrono/manager/templates/chrono/manager_events_agenda_settings.html
index 4c82948e..274b56a5 100644
--- a/chrono/manager/templates/chrono/manager_events_agenda_settings.html
+++ b/chrono/manager/templates/chrono/manager_events_agenda_settings.html
@@ -12,158 +12,157 @@
   {% endif %}{% endwith %}
 {% endblock %}
 
-{% block agenda-settings %}
+{% block agenda-settings-extra-tab-buttons %}
+    <button aria-controls="panel-events" aria-selected="true" id="tab-events" role="tab" tabindex="0">{% trans "Events" %}</button>
+    {% if has_recurring_events %}
+    <button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Recurrence exceptions" %}</button>
+    {% endif %}
+    <button aria-controls="panel-display-options" aria-selected="false" id="tab-display-options" role="tab" tabindex="-1">{% trans "Display options" %}</button>
+    <button aria-controls="panel-booking-check-options" aria-selected="false" id="tab-booking-check-options" role="tab" tabindex="-1">{% trans "Booking check options" %}</button>
+    <button aria-controls="panel-notifications" aria-selected="false" id="tab-notifications" role="tab" tabindex="-1">{% trans "Notifications" %}</button>
+{% endblock %}
+
+{% block agenda-settings-extra-tab-list %}
 
-<div class="section">
-<h3>{% trans "Events" %}</h3>
-<div>
-{% with view.get_events as events %}
-{% if events %}
-  <ul class="objects-list single-links">
-  {% for event in events %}
-    {% include 'chrono/manager_agenda_event_fragment.html' with view_mode='settings_view' %}
-  {% endfor %}
-  </ul>
-{% else %}
-<div class="big-msg-info">
-  {% blocktrans %}
-  This agenda doesn't have any event yet. Click on the "New Event" button in
-  the top right of the page to add a first one.
-  {% endblocktrans %}
-</div>
-{% endif %}
-{% endwith %}
-</div>
-</div>
+    <div aria-labelledby="tab-events" id="panel-events" role="tabpanel" tabindex="0">
+      {% with view.get_events as events %}
+      {% if events %}
+        <ul class="objects-list single-links">
+        {% for event in events %}
+          {% include 'chrono/manager_agenda_event_fragment.html' with view_mode='settings_view' %}
+        {% endfor %}
+        </ul>
+      {% else %}
+      <div class="big-msg-info">
+        {% blocktrans %}
+        This agenda doesn't have any event yet. Click on the "New Event" button in
+        the top right of the page to add a first one.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
+      {% endwith %}
+    </div>
 
-<div class="section">
-<h3>{% trans "Display options" %}
-    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-    <ul>
+    {% if has_recurring_events %}
+    <div aria-labelledby="tab-time-periods" hidden="" id="panel-time-periods" role="tabpanel" tabindex="0">
+      {% if object.recurrence_exceptions_report.events.exists %}
+      <div class="warningnotice">
+        <p>{% trans "The following events exist despite exceptions because they have active bookings:" %}</p>
+        <ul>
+          {% for event in object.recurrence_exceptions_report.events.all %}
+          <li><a href="{{ event.get_absolute_view_url }}">{{ event }}{% if event.label %} - {{ event.start_datetime|date:"DATETIME_FORMAT" }}{% endif %}</a></li>
+          {% endfor %}
+        </ul>
+        <p>{% trans "You can cancel them manually for this warning to go away, or wait until they are passed." %}</p>
+      </div>
+      {% endif %}
+      <ul class="objects-list single-links">
+        {% for exception in exceptions|slice:":5" %}
         <li>
-            {% if agenda.event_display_template %}
-                {% trans "Event display template:" %}
-                <pre>{{ agenda.event_display_template }}</pre>
-            {% else %}
-            {% trans "No event display template configured for this agenda." %}
-            {% endif %}
+          <a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>{{ exception }}</a>
+          {% if not exception.read_only %}
+          <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
+          {% endif %}
         </li>
+        {% endfor %}
+        {% if exceptions|length > 5 %}
+        <li><a class="timeperiod-exception-all desk-{{ desk.pk }}" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-extract-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
+        {% endif %}
+        <li><a class="add" rel="popup" href="{% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk %}">{% trans 'Add a time period exception' %}</a></li>
+      </ul>
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
+    {% endif %}
+
+    <div aria-labelledby="tab-display-options" hidden="" id="panel-display-options" role="tabpanel" tabindex="0">
+      <ul>
         <li>
-            {% trans "Booking display template:" %}
-            <pre>{{ agenda.get_booking_user_block_template }}</pre>
+          {% if agenda.event_display_template %}
+            {% trans "Event display template:" %}
+            <pre>{{ agenda.event_display_template }}</pre>
+          {% else %}
+          {% trans "No event display template configured for this agenda." %}
+          {% endif %}
         </li>
-    </ul>
-</div>
-</div>
+        <li>
+          {% trans "Booking display template:" %}
+          <pre>{{ agenda.get_booking_user_block_template }}</pre>
+        </li>
+      </ul>
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
 
-<div class="section">
-<h3>{% trans "Booking check options" %}
-    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-    <ul>
-    {% if has_check_types %}
+    <div aria-labelledby="tab-booking-check-options" hidden="" id="panel-booking-check-options" role="tabpanel" tabindex="0">
+      <ul>
+        {% if has_check_types %}
         {% if agenda.check_type_group %}
         <li>{% trans "Check type group:" %} {{ agenda.check_type_group }}
-            <ul>
-                <li>{% trans "Absences:" %}
-                    <ul>
-                      {% for check_type in agenda.check_type_group.check_types.absences %}
-                      <li>{{ check_type }}</li>
-                      {% empty %}
-                      <li>({% trans "No absence check type defined" %})</li>
-                      {% endfor %}
-                    </ul>
-                </li>
-                <li>{% trans "Presences:" %}
-                    <ul>
-                      {% for check_type in agenda.check_type_group.check_types.presences %}
-                      <li>{{ check_type }}</li>
-                      {% empty %}
-                      <li>({% trans "No presence check type defined" %})</li>
-                      {% endfor %}
-                    </ul>
-                </li>
-            </ul>
+          <ul>
+            <li>{% trans "Absences:" %}
+              <ul>
+                {% for check_type in agenda.check_type_group.check_types.absences %}
+                <li>{{ check_type }}</li>
+                {% empty %}
+                <li>({% trans "No absence check type defined" %})</li>
+                {% endfor %}
+              </ul>
+            </li>
+            <li>{% trans "Presences:" %}
+              <ul>
+                {% for check_type in agenda.check_type_group.check_types.presences %}
+                <li>{{ check_type }}</li>
+                {% empty %}
+                <li>({% trans "No presence check type defined" %})</li>
+                {% endfor %}
+              </ul>
+            </li>
+          </ul>
         </li>
         {% else %}
         <li>{% trans "No check types configured for this agenda." %}</li>
         {% endif %}
-    {% endif %}
+        {% endif %}
 
-    {% with agenda.get_booking_check_filters as check_filters %}
-        {% if check_filters %}
-        <li>{% trans "Filters:" %}
+        {% with agenda.get_booking_check_filters as check_filters %}
+          {% if check_filters %}
+          <li>{% trans "Filters:" %}
             <ul>
-                {% for key in check_filters %}
-                <li>{{ key }}</li>
-                {% endfor %}
+              {% for key in check_filters %}
+              <li>{{ key }}</li>
+              {% endfor %}
             </ul>
-        </li>
-        {% else %}
-        <li>{% trans "No filters configured for this agenda." %}</li>
-        {% endif %}
-    {% endwith %}
-
+          </li>
+          {% else %}
+          <li>{% trans "No filters configured for this agenda." %}</li>
+          {% endif %}
+        {% endwith %}
         <li>{% trans "Automatically mark event as checked when all bookings have been checked:" %} {{ agenda.mark_event_checked_auto|yesno }}</li>
         <li>{% trans "Prevent the check of bookings when event was marked as checked:" %} {{ agenda.disable_check_update|yesno }}</li>
-    </ul>
-</div>
-</div>
-
-<div class="section">
-<h3>{% trans "Notifications" %}
-<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-notifications-settings' pk=object.id %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-{% for notification_type in object.notifications_settings.get_notification_types %}
-{% if forloop.first %}<ul>{% endif %}
-  <li>
-  {% blocktrans trimmed with display_value=notification_type.display_value label=notification_type.label %}
-  {{ label }}: {{ display_value }} will be notified.
-  {% endblocktrans %}
-  </li>
-{% if forloop.last %}</ul>{% endif %}
-{% empty %}
-<p>{% trans "Notifications are disabled for this agenda." %}</p>
-{% endfor %}
-</div>
-</div>
+      </ul>
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
 
-{% if has_recurring_events %}
-<div class="section">
-<h3>{% trans "Recurrence exceptions" %}
-<a rel="popup" class="button" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-{% if object.recurrence_exceptions_report.events.exists %}
-<div class="warningnotice">
-<p>{% trans "The following events exist despite exceptions because they have active bookings:" %}</p>
-<ul>
-{% for event in object.recurrence_exceptions_report.events.all %}
-<li><a href="{{ event.get_absolute_view_url }}">{{ event }}{% if event.label %} - {{ event.start_datetime|date:"DATETIME_FORMAT" }}{% endif %}</a></li>
-{% endfor %}
-</ul>
-<p>{% trans "You can cancel them manually for this warning to go away, or wait until they are passed." %}</p>
-</div>
-{% endif %}
-<ul class="objects-list single-links">
-{% for exception in exceptions|slice:":5" %}
-   <li><a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>
-  {{ exception }}
-  {% if not exception.read_only %}
-  <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
-  {% endif %}
-{% endfor %}
-{% if exceptions|length > 5 %}
-<li><a class="timeperiod-exception-all desk-{{ desk.pk }}" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-extract-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
-{% endif %}
-<li><a class="add" rel="popup" href="{% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk %}">{% trans 'Add a time period exception' %}</a></li>
-</ul>
-</div>
-</div>
-{% endif %}
+    <div aria-labelledby="tab-notifications" hidden="" id="panel-notifications" role="tabpanel" tabindex="0">
+      {% for notification_type in object.notifications_settings.get_notification_types %}
+      {% if forloop.first %}<ul>{% endif %}
+        <li>
+        {% blocktrans trimmed with display_value=notification_type.display_value label=notification_type.label %}
+        {{ label }}: {{ display_value }} will be notified.
+        {% endblocktrans %}
+        </li>
+      {% if forloop.last %}</ul>{% endif %}
+      {% empty %}
+        <p>{% trans "Notifications are disabled for this agenda." %}</p>
+      {% endfor %}
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-notifications-settings' pk=object.id %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
 
 {% endblock %}
diff --git a/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html b/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
index d0bf1a77..d9eb9399 100644
--- a/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
+++ b/chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
@@ -26,145 +26,149 @@
   {% endif %}
 {% endblock %}
 
-{% block agenda-settings %}
+{% block agenda-settings-extra-tab-buttons %}
+    <button aria-controls="panel-meeting-types" aria-selected="true" id="tab-meeting-types" role="tab" tabindex="0">{% trans "Meeting Types" %}</button>
+    {% if object.desk_simple_management %}
+    <button aria-controls="panel-desks" aria-selected="false" id="tab-desks" role="tab" tabindex="-1">{% trans "Desks" %}</button>
+    {% endif %}
+    <button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Time Periods" %}</button>
+    {% if has_resources %}
+    <button aria-controls="panel-resources" aria-selected="false" id="tab-resources" role="tab" tabindex="-1">{% trans "Resources" %}</button>
+    {% endif %}
+    <button aria-controls="panel-display-options" aria-selected="false" id="tab-display-options" role="tab" tabindex="-1">{% trans "Display options" %}</button>
+{% endblock %}
+
+{% block agenda-settings-extra-tab-list %}
 
-<div class="section">
-<h3>{% trans 'Meeting Types' %}</h3>
-<div>
-{% if meeting_types %}
-  <ul class="objects-list single-links">
-    {% for meeting_type in meeting_types %}
-    <li><a rel="popup" href="{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}">
-        {{meeting_type.label}}
-        <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
-        <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
-        </a>
-        <a rel="popup" class="delete" href="{% url 'chrono-manager-meeting-type-delete' pk=meeting_type.id %}">{% trans "remove" %}</a>
-    </li>
-    {% endfor %}
-  </ul>
-{% else %}
-<div class="big-msg-info">
-  {% blocktrans %}
-  This agenda doesn't have any meeting type yet. Click on the "New Meeting Type" button in
-  the top right of the page to add a first one.
-  {% endblocktrans %}
-</div>
-{% endif %}
-</div>
-</div>
+    <div aria-labelledby="tab-meeting-types" id="panel-meeting-types" role="tabpanel" tabindex="0">
+      {% if meeting_types %}
+      <ul class="objects-list single-links">
+        {% for meeting_type in meeting_types %}
+        <li>
+          <a rel="popup" href="{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}">
+            {{meeting_type.label}}
+            <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
+            <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
+          </a>
+          <a rel="popup" class="delete" href="{% url 'chrono-manager-meeting-type-delete' pk=meeting_type.id %}">{% trans "remove" %}</a>
+        </li>
+        {% endfor %}
+      </ul>
+      {% else %}
+      <div class="big-msg-info">
+        {% blocktrans %}
+        This agenda doesn't have any meeting type yet. Click on the "New Meeting Type" button in
+        the top right of the page to add a first one.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
+    </div>
 
-{% if object.desk_simple_management %}
-<div class="section">
-<h3>{% trans 'Desks' %}</h3>
-<div>
-    <ul class="objects-list single-links">
+    {% if object.desk_simple_management %}
+    <div aria-labelledby="tab-desks" hidden="" id="panel-desks" role="tabpanel" tabindex="0">
+      <ul class="objects-list single-links">
         {% for desk in object.prefetched_desks %}
-            <li>
-                <a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.pk %}">{{ desk.label }}</a>
-                <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.pk %}">{% trans "remove" %}</a>
-            </li>
+          <li>
+            <a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.pk %}">{{ desk.label }}</a>
+            <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.pk %}">{% trans "remove" %}</a>
+          </li>
         {% endfor %}
-    </ul>
-</div>
-</div>
-{% endif %}
+      </ul>
+    </div>
+    {% endif %}
 
-<div class="section">
-<h3>{% trans 'Time Periods' %}</h3>
-<div>
-    {% if object.prefetched_desks %}
-    <div class="timeperiods">
+    <div aria-labelledby="tab-time-periods" hidden="" id="panel-time-periods" role="tabpanel" tabindex="0">
+      {% if object.prefetched_desks %}
+      <div class="timeperiods">
         {% for desk in object.prefetched_desks %}
         {% if not object.desk_simple_management or object.desk_simple_management and forloop.counter == 1 %}
         <div class="timeperiod">
-            {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
-            <ul class="objects-list single-links">
-                {% if not object.desk_simple_management and object.prefetched_desks|length > 1 %}
-                <li><a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.id %}">
-                    <strong>{{ desk.label }}</strong>
-                    </a>
-                   <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.id %}">{% trans "remove" %}</a>
-                </li>
-                {% endif %}
-                {% for time_period in desk.timeperiod_set.all %}
-                <li><a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
-                <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
-
-                </li>
-                {% endfor %}
-                <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
-                {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
-                <li><a><strong>{% trans 'Exceptions' %}</strong></a><a class="link-action-icon settings" rel="popup" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}" title="{% trans 'Manage exception sources' %}">{% trans 'manage exceptions' %}</a></li>
-                {% for exception in desk.get_exceptions_within_two_weeks %}
-                     <li><a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>
-                    {{ exception }}
-                    {% if not exception.read_only %}
-                    <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
-                    {% endif %}
-                {% endfor %}
-                {% if not desk.are_all_exceptions_displayed %}
-                <li><a class="timeperiod-exception-all desk-{{ desk.pk }}" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-extract-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
-                {% endif %}
-                <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
-            </ul>
+          {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
+          <ul class="objects-list single-links">
+            {% if not object.desk_simple_management and object.prefetched_desks|length > 1 %}
+            <li>
+              <a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.id %}">
+                <strong>{{ desk.label }}</strong>
+              </a>
+              <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.id %}">{% trans "remove" %}</a>
+            </li>
+            {% endif %}
+            {% for time_period in desk.timeperiod_set.all %}
+            <li>
+              <a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
+              <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
+            </li>
+            {% endfor %}
+            <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
+            {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
+            <li>
+              <a><strong>{% trans 'Exceptions' %}</strong></a>
+              <a class="link-action-icon settings" rel="popup" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}" title="{% trans 'Manage exception sources' %}">{% trans 'manage exceptions' %}</a>
+            </li>
+            {% for exception in desk.get_exceptions_within_two_weeks %}
+            <li>
+              <a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>{{ exception }}</a>
+              {% if not exception.read_only %}
+              <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
+              {% endif %}
+            </li>
+            {% endfor %}
+            {% if not desk.are_all_exceptions_displayed %}
+            <li><a class="timeperiod-exception-all desk-{{ desk.pk }}" rel="popup" data-selector="div.timeperiod" href="{% url 'chrono-manager-time-period-exception-extract-list' pk=desk.id %}">({% trans 'see all exceptions' %})</a></li>
+            {% endif %}
+            <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
+          </ul>
         </div>
         {% endif %}
         {% endfor %}
+      </div>
+      {% else %}
+      <div class="big-msg-info">
+        {% blocktrans %}
+        This agenda doesn't have any desk yet. Click on the "New Desk" button in
+        the top right of the page to add a first one.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
     </div>
-    {% else %}
-    <div class="big-msg-info">
-    {% blocktrans %}
-    This agenda doesn't have any desk yet. Click on the "New Desk" button in
-    the top right of the page to add a first one.
-    {% endblocktrans %}
-    </div>
-    {% endif %}
-</div>
-</div>
 
-{% with object.resources.all as agenda_resources %}
-{% if has_resources %}
-<div class="section">
-<h3>{% trans 'Resources' %}</h3>
-<div>
-{% if agenda_resources %}
-  <ul class="objects-list single-links">
-    {% for resource in agenda_resources %}
-    <li>
-        <a href="{% url 'chrono-manager-resource-view' pk=resource.pk %}">
+    {% if has_resources %}
+    <div aria-labelledby="tab-resources" hidden="" id="panel-resources" role="tabpanel" tabindex="0">
+      {% with object.resources.all as agenda_resources %}
+      {% if agenda_resources %}
+      <ul class="objects-list single-links">
+        {% for resource in agenda_resources %}
+        <li>
+          <a href="{% url 'chrono-manager-resource-view' pk=resource.pk %}">
             {{ resource.label }}
             <span class="identifier">[{% trans "identifier:" %} {{ resource.slug }}]</span>
-        </a>
-        <a rel="popup" class="delete" href="{% url 'chrono-manager-agenda-delete-resource' pk=object.pk resource_pk=resource.pk %}">{% trans "remove" %}</a>
-    </li>
-    {% endfor %}
-  </ul>
-{% else %}
-<div class="big-msg-info">
-  {% blocktrans %}
-  This agenda doesn't have any resource yet. Click on the "Add resource" button in
-  the top right of the page to add a first one.
-  {% endblocktrans %}
-</div>
-{% endif %}
-</div>
-</div>
-{% endif %}
-{% endwith %}
+          </a>
+          <a rel="popup" class="delete" href="{% url 'chrono-manager-agenda-delete-resource' pk=object.pk resource_pk=resource.pk %}">{% trans "remove" %}</a>
+        </li>
+        {% endfor %}
+      </ul>
+      {% else %}
+      <div class="big-msg-info">
+        {% blocktrans %}
+        This agenda doesn't have any resource yet. Click on the "Add resource" button in
+        the top right of the page to add a first one.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
+      {% endwith %}
+    </div>
+    {% endif %}
 
-<div class="section">
-<h3>{% trans "Display options" %}
-    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
-</h3>
-<div>
-    <ul>
+    <div aria-labelledby="tab-display-options" hidden="" id="panel-display-options" role="tabpanel" tabindex="0">
+      <ul>
         <li>
-            {% trans "Booking display template:" %}
-            <pre>{{ agenda.get_booking_user_block_template }}</pre>
+          {% trans "Booking display template:" %}
+          <pre>{{ agenda.get_booking_user_block_template }}</pre>
         </li>
-    </ul>
-</div>
-</div>
+      </ul>
+      <div class="panel--buttons">
+        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
+      </div>
+    </div>
 
 {% endblock %}
diff --git a/chrono/manager/templates/chrono/manager_virtual_agenda_settings.html b/chrono/manager/templates/chrono/manager_virtual_agenda_settings.html
index 006c981c..ae903c6a 100644
--- a/chrono/manager/templates/chrono/manager_virtual_agenda_settings.html
+++ b/chrono/manager/templates/chrono/manager_virtual_agenda_settings.html
@@ -6,75 +6,81 @@
   <a rel="popup" href="{% url 'chrono-manager-agenda-add-virtual-member' pk=object.id %}">{% trans 'Include Agenda' %}</a>
 {% endblock %}
 
-{% block agenda-settings %}
+{% block agenda-settings-extra-tab-buttons %}
+    <button aria-controls="panel-agendas" aria-selected="true" id="tab-agendas" role="tab" tabindex="0">{% trans "Included Agendas" %}</button>
+   {% if virtual_members %}
+    <button aria-controls="panel-meeting-types" aria-selected="false" id="tab-meeting-types" role="tab" tabindex="-1">{% trans "Meeting Types" %}</button>
+    {% endif %}
+    <button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Excluded Periods" %}</button>
+{% endblock %}
 
-<div class="section">
-<h3>{% trans 'Included Agendas' %}</h3>
-<div>
-{% if virtual_members %}
-  <ul class="objects-list single-links">
-    {% for virtual_member, can_be_managed in virtual_members %}
-    <li><a {% if can_be_managed %}href="{% url 'chrono-manager-agenda-settings' pk=virtual_member.real_agenda.id %}"{% endif %}>
-        {{virtual_member.real_agenda.label}}
-        </a>
-        <a rel="popup" class="delete" href="{% url 'chrono-manager-virtual-member-delete' pk=virtual_member.pk %}">{% trans "remove" %}</a>
-    </li>
-    {% endfor %}
-  </ul>
-{% else %}
-<div class="big-msg-info">
-  {% blocktrans %}
-  This virtual agenda doesn't include any agenda yet. Click on the "Include Agenda" button in
-  the top right of the page to include a first one.
-  {% endblocktrans %}
-</div>
-{% endif %}
-</div>
-</div>
+{% block agenda-settings-extra-tab-list %}
 
-{% if virtual_members %}
-<div class="section">
-<h3>{% trans 'Meeting Types' %}</h3>
-<div>
-{% if meeting_types %}
-  <ul class="objects-list single-links">
-    {% for meeting_type in meeting_types %}
-    <li><a rel="popup" href="">
-        {{meeting_type.label}}
-        <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
-        <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
-        </a>
-    </li>
-    {% endfor %}
-  </ul>
-{% else %}
-<div class="errornotice">
-  {% blocktrans %}
-  This virtual agenda doesn't have any meeting type.
-  It is probably because its included agendas have incompatible meeting types
-  and it makes this virtual agenda unusable.
-  {% endblocktrans %}
-</div>
-{% endif %}
-</div>
-</div>
-{% endif %}
+    <div aria-labelledby="tab-agendas" id="panel-agendas" role="tabpanel" tabindex="0">
+      {% if virtual_members %}
+      <ul class="objects-list single-links">
+        {% for virtual_member, can_be_managed in virtual_members %}
+        <li>
+          <a {% if can_be_managed %}href="{% url 'chrono-manager-agenda-settings' pk=virtual_member.real_agenda.id %}"{% endif %}>
+            {{virtual_member.real_agenda.label}}
+          </a>
+          <a rel="popup" class="delete" href="{% url 'chrono-manager-virtual-member-delete' pk=virtual_member.pk %}">{% trans "remove" %}</a>
+        </li>
+        {% endfor %}
+      </ul>
+      {% else %}
+      <div class="big-msg-info">
+        {% blocktrans %}
+        This virtual agenda doesn't include any agenda yet. Click on the "Include Agenda" button in
+        the top right of the page to include a first one.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
+    </div>
 
-{% if agenda.excluded_timeperiods.count %}
-<div class="section">
-<h3>{% trans 'Excluded Periods' %}</h3>
-<div>
-  <ul class="objects-list single-links">
-    {% for time_period in agenda.excluded_timeperiods.all %}
-    <li><a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
-      <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
-    </li>
-    {% endfor %}
-  </ul>
-</div>
-</div>
-{% endif %}
+   {% if virtual_members %}
+    <div aria-labelledby="tab-meeting-types" hidden="" id="panel-meeting-types" role="tabpanel" tabindex="0">
+      {% if meeting_types %}
+      <ul class="objects-list single-links">
+        {% for meeting_type in meeting_types %}
+        <li>
+          <a rel="popup" href="">
+            {{meeting_type.label}}
+            <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
+            <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
+          </a>
+        </li>
+        {% endfor %}
+      </ul>
+      {% else %}
+      <div class="errornotice">
+        {% blocktrans %}
+        This virtual agenda doesn't have any meeting type.
+        It is probably because its included agendas have incompatible meeting types
+        and it makes this virtual agenda unusable.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
+    </div>
+    {% endif %}
+
+    <div aria-labelledby="tab-time-periods" hidden="" id="panel-time-periods" role="tabpanel" tabindex="0">
+      {% if agenda.excluded_timeperiods.count %}
+      <ul class="objects-list single-links">
+        {% for time_period in agenda.excluded_timeperiods.all %}
+        <li><a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
+          <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
+        </li>
+        {% endfor %}
+      </ul>
+      {% else %}
+      <div class="big-msg-info">
+        {% blocktrans %}
+        This virtual agenda doesn't have any excluded period yet. Click on the "Add Excluded Period" button in
+        the top right of the page to include a first one.
+        {% endblocktrans %}
+      </div>
+      {% endif %}
+    </div>
 
-{% block agenda-reminder %}
-{% endblock %}
 {% endblock %}
diff --git a/tests/manager/test_all.py b/tests/manager/test_all.py
index 69f2b9c2..5d1ee271 100644
--- a/tests/manager/test_all.py
+++ b/tests/manager/test_all.py
@@ -2134,11 +2134,11 @@ def test_virtual_agenda_settings_empty(app, admin_user):
     assert 'Delete' in resp.text
     assert 'Included Agendas' in resp.text
     assert 'Add Excluded Period' in resp.text
+    assert 'Excluded Periods' in resp.text
+    assert "This virtual agenda doesn't have any excluded period yet" in resp.text
     assert "This virtual agenda doesn't include any agenda yet" in resp.text
     # No meeting types yet
     assert 'Meeting Types' not in resp.text
-    # No absence yet
-    assert 'Excluded Periods' not in resp.text
 
 
 def test_virtual_agenda_settings(app, admin_user):
diff --git a/tests/manager/test_exception.py b/tests/manager/test_exception.py
index 321a3e86..639aed65 100644
--- a/tests/manager/test_exception.py
+++ b/tests/manager/test_exception.py
@@ -94,7 +94,7 @@ def test_meetings_agenda_add_time_period_exception(app, admin_user):
         hour=16
     ).strftime(dt_format)
     # add an exception beyond 2 weeks and make sure it isn't listed
-    resp = resp.click('Add a time period exception', index=1)
+    resp = resp.click('Add a time period exception', index=0)
     future = tomorrow + datetime.timedelta(days=15)
     resp.form['label'] = 'Exception 2'
     resp.form['start_datetime_0'] = future.strftime('%Y-%m-%d')
-- 
2.35.1

