Projet

Général

Profil

0001-manager-use-sidetabs-to-navigate-between-agenda-sett.patch

Lauréline Guérin, 24 mai 2022 22:19

Télécharger (43,6 ko)

Voir les différences:

Subject: [PATCH 1/2] manager: use sidetabs to navigate between agenda settings
 (#65653)

 chrono/manager/static/css/style.scss          |   9 +
 .../chrono/manager_agenda_settings.html       | 132 ++++----
 .../manager_events_agenda_settings.html       | 309 +++++++++---------
 .../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, 433 insertions(+), 411 deletions(-)
chrono/manager/static/css/style.scss
523 523
	height: 20px;
524 524
}
525 525

  
526
div.agenda-settings .pk-tabs--container {
527
    & > div {
528
        padding: 1ex;
529
        .panel--buttons a.button {
530
            line-height: inherit;
531
        }
532
    }
533
}
534

  
526 535
div.paragraph {
527 536
	background: white;
528 537
	box-sizing: border-box;
chrono/manager/templates/chrono/manager_agenda_settings.html
35 35

  
36 36
{% block content %}
37 37

  
38
{% block agenda-settings %}
39
{% endblock %}
38
<div class="section agenda-settings">
39
<div class="pk-tabs">
40
  <div class="pk-tabs--tab-list" role="tablist">
41
    {% block agenda-settings-extra-tab-buttons %}{% endblock %}
42
    {% if object.kind != 'virtual' %}
43
    <button aria-controls="panel-reminders" aria-selected="false" id="tab-reminders" role="tab" tabindex="-1">{% trans "Booking reminders" %}</button>
44
    {% endif %}
45
    <button aria-controls="panel-delays" aria-selected="false" id="tab-delays" role="tab" tabindex="-1">{% trans "Booking Delays" %}</button>
46
    <button aria-controls="panel-permissions" aria-selected="false" id="tab-permissions" role="tab" tabindex="-1">{% trans "Permissions" %}</button>
47
  </div>
48
  <div class="pk-tabs--container">
40 49

  
41
{% block agenda-reminder %}
42
<div class="section">
43
<h3>{% trans "Booking reminders" %}
44
<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-reminder-settings' pk=object.id %}">{% trans "Configure" %}</a>
45
</h3>
46
<div>
47
{% for info in agenda.reminder_settings.display_info %}
48
<p>{{ info }}</p>
49
{% empty %}
50
<p>{% trans "Reminders are disabled for this agenda." %}</p>
51
{% endfor %}
52
<p>
53
{% if agenda.reminder_settings.days_before_email %}
54
<a rel="popup" data-selector="#message-preview" href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='email' %}">{% trans "Preview email" %}</a>
55
{% endif %}
56
{% if agenda.reminder_settings.days_before_sms %}
57
<a rel="popup" data-selector="#message-preview"  href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='sms' %}">{% trans "Preview SMS" %}</a>
58
{% endif %}
59
</p>
60
{% if agenda.reminder_settings.days_before_email or agenda.reminder_settings.days_before_sms %}
61
<p>
62
<a rel="popup" href="{% url 'chrono-manager-agenda-reminder-test' pk=object.pk %}">{% trans "Test reminder sending" %}</a>
63
</p>
64
{% endif %}
65
</div>
66
</div>
67
{% endblock %}
50
    {% block agenda-settings-extra-tab-list %}{% endblock %}
68 51

  
69
{% block agenda-permissions %}
70
<div class="section">
71
<h3>{% trans "Permissions" %}
72
<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-roles' pk=object.id %}">{% trans 'Configure' %}</a>
73
</h3>
74
<div>
75
<ul>
76
  <li>{% trans "Edit Role:" %} {% if agenda.edit_role %}{{ agenda.edit_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
77
  <li>{% trans "View Role:" %} {% if agenda.view_role %}{{ agenda.view_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
78
</ul>
79
</div>
80
</div>
81
{% endblock %}
82

  
83
{% block agenda-booking-delays %}
84
<div class="section">
85
<h3>{% trans "Booking Delays" %}
86
<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-delays' pk=object.id %}">{% trans 'Configure' %}</a>
87
</h3>
88
<div>
89
<ul>
90
  <li>{% trans "Minimal booking delay:" %}
91
      {% if agenda.minimal_booking_delay is not None %}
92
        {% if agenda.minimal_booking_delay_in_working_days %}
93
        {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} working day{% plural %}{{ count }} working days{% endblocktrans %}
94
        {% else %}
95
        {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
52
    {% if object.kind != 'virtual' %}
53
    <div aria-labelledby="tab-reminders" id="panel-reminders" role="tabpanel" tabindex="0" hidden="">
54
      {% for info in agenda.reminder_settings.display_info %}
55
      <p>{{ info }}</p>
56
      {% empty %}
57
      <p>{% trans "Reminders are disabled for this agenda." %}</p>
58
      {% endfor %}
59
      <p>
60
        {% if agenda.reminder_settings.days_before_email %}
61
        <a rel="popup" data-selector="#message-preview" href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='email' %}">{% trans "Preview email" %}</a>
62
        {% endif %}
63
        {% if agenda.reminder_settings.days_before_sms %}
64
        <a rel="popup" data-selector="#message-preview"  href="{% url 'chrono-manager-agenda-reminder-preview' pk=object.id type='sms' %}">{% trans "Preview SMS" %}</a>
96 65
        {% endif %}
97
      {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
98
  <li>{% trans "Maximal booking delay:" %}
99
      {% if agenda.maximal_booking_delay is not None %}
100
        {% blocktrans count count=agenda.maximal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
101
      {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
102
</ul>
66
      </p>
67
      {% if agenda.reminder_settings.days_before_email or agenda.reminder_settings.days_before_sms %}
68
      <p>
69
        <a rel="popup" href="{% url 'chrono-manager-agenda-reminder-test' pk=object.pk %}">{% trans "Test reminder sending" %}</a>
70
      </p>
71
      {% endif %}
72
      <div class="panel--buttons">
73
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-reminder-settings' pk=object.id %}">{% trans "Configure" %}</a>
74
      </div>
75
    </div>
76
    {% endif %}
77

  
78
    <div aria-labelledby="tab-delays" hidden="" id="panel-delays" role="tabpanel" tabindex="0">
79
      <ul>
80
        <li>{% trans "Minimal booking delay:" %}
81
            {% if agenda.minimal_booking_delay is not None %}
82
              {% if agenda.minimal_booking_delay_in_working_days %}
83
              {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} working day{% plural %}{{ count }} working days{% endblocktrans %}
84
              {% else %}
85
              {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
86
              {% endif %}
87
            {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
88
        <li>{% trans "Maximal booking delay:" %}
89
            {% if agenda.maximal_booking_delay is not None %}
90
              {% blocktrans count count=agenda.maximal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
91
            {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
92
      </ul>
93
      <div class="panel--buttons">
94
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-delays' pk=object.id %}">{% trans 'Configure' %}</a>
95
      </div>
96
    </div>
97

  
98
    <div aria-labelledby="tab-permissions" hidden="" id="panel-permissions" role="tabpanel" tabindex="0">
99
      <ul>
100
        <li>{% trans "Edit Role:" %} {% if agenda.edit_role %}{{ agenda.edit_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
101
        <li>{% trans "View Role:" %} {% if agenda.view_role %}{{ agenda.view_role }}{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
102
      </ul>
103
      <div class="panel--buttons">
104
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-roles' pk=object.id %}">{% trans 'Configure' %}</a>
105
      </div>
106
    </div>
107

  
108
  </div>
103 109
</div>
104 110
</div>
105 111
{% endblock %}
106

  
107
{% endblock %}
chrono/manager/templates/chrono/manager_events_agenda_settings.html
9 9
  {% endif %}
10 10
{% endblock %}
11 11

  
12
{% block agenda-settings %}
12
{% block agenda-settings-extra-tab-buttons %}
13
    <button aria-controls="panel-events" aria-selected="true" id="tab-events" role="tab" tabindex="0">{% trans "Events" %}</button>
14
    {% if has_recurring_events %}
15
    <button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Recurrence exceptions" %}</button>
16
    {% endif %}
17
    <button aria-controls="panel-display-options" aria-selected="false" id="tab-display-options" role="tab" tabindex="-1">{% trans "Display options" %}</button>
18
    <button aria-controls="panel-booking-check-options" aria-selected="false" id="tab-booking-check-options" role="tab" tabindex="-1">{% trans "Booking check options" %}</button>
19
    {% if pricing_enabled %}
20
    <button aria-controls="panel-pricing" aria-selected="false" id="tab-booking-check-options" role="tab" tabindex="-1">{% trans "Pricing" context 'pricing' %}</button>
21
    {% endif %}
22
    <button aria-controls="panel-notifications" aria-selected="false" id="tab-notifications" role="tab" tabindex="-1">{% trans "Notifications" %}</button>
23
{% endblock %}
24

  
25
{% block agenda-settings-extra-tab-list %}
13 26

  
14
<div class="section">
15
<h3>{% trans "Events" %}</h3>
16
<div>
17
{% with view.get_events as events %}
18
{% if events %}
19
  <ul class="objects-list single-links">
20
  {% for event in events %}
21
    {% include 'chrono/manager_agenda_event_fragment.html' with view_mode='settings_view' %}
22
  {% endfor %}
23
  </ul>
24
{% else %}
25
<div class="big-msg-info">
26
  {% blocktrans %}
27
  This agenda doesn't have any event yet. Click on the "New Event" button in
28
  the top right of the page to add a first one.
29
  {% endblocktrans %}
30
</div>
31
{% endif %}
32
{% endwith %}
33
</div>
34
</div>
27
    <div aria-labelledby="tab-events" id="panel-events" role="tabpanel" tabindex="0">
28
      {% with view.get_events as events %}
29
      {% if events %}
30
        <ul class="objects-list single-links">
31
        {% for event in events %}
32
          {% include 'chrono/manager_agenda_event_fragment.html' with view_mode='settings_view' %}
33
        {% endfor %}
34
        </ul>
35
      {% else %}
36
      <div class="big-msg-info">
37
        {% blocktrans %}
38
        This agenda doesn't have any event yet. Click on the "New Event" button in
39
        the top right of the page to add a first one.
40
        {% endblocktrans %}
41
      </div>
42
      {% endif %}
43
      {% endwith %}
44
    </div>
35 45

  
36
<div class="section">
37
<h3>{% trans "Display options" %}
38
    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
39
</h3>
40
<div>
41
    <ul>
46
    {% if has_recurring_events %}
47
    <div aria-labelledby="tab-time-periods" hidden="" id="panel-time-periods" role="tabpanel" tabindex="0">
48
      {% if object.recurrence_exceptions_report.events.exists %}
49
      <div class="warningnotice">
50
        <p>{% trans "The following events exist despite exceptions because they have active bookings:" %}</p>
51
        <ul>
52
          {% for event in object.recurrence_exceptions_report.events.all %}
53
          <li><a href="{{ event.get_absolute_view_url }}">{{ event }}{% if event.label %} - {{ event.start_datetime|date:"DATETIME_FORMAT" }}{% endif %}</a></li>
54
          {% endfor %}
55
        </ul>
56
        <p>{% trans "You can cancel them manually for this warning to go away, or wait until they are passed." %}</p>
57
      </div>
58
      {% endif %}
59
      <ul class="objects-list single-links">
60
        {% for exception in exceptions|slice:":5" %}
42 61
        <li>
43
            {% if agenda.event_display_template %}
44
                {% trans "Event display template:" %}
45
                <pre>{{ agenda.event_display_template }}</pre>
46
            {% else %}
47
            {% trans "No event display template configured for this agenda." %}
48
            {% endif %}
62
          <a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>{{ exception }}</a>
63
          {% if not exception.read_only %}
64
          <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
65
          {% endif %}
49 66
        </li>
67
        {% endfor %}
68
        {% if exceptions|length > 5 %}
69
        <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>
70
        {% endif %}
71
        <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>
72
      </ul>
73
      <div class="panel--buttons">
74
        <a rel="popup" class="button" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}">{% trans 'Configure' %}</a>
75
      </div>
76
    </div>
77
    {% endif %}
78

  
79
    <div aria-labelledby="tab-display-options" hidden="" id="panel-display-options" role="tabpanel" tabindex="0">
80
      <ul>
50 81
        <li>
51
            {% trans "Booking display template:" %}
52
            <pre>{{ agenda.get_booking_user_block_template }}</pre>
82
          {% if agenda.event_display_template %}
83
            {% trans "Event display template:" %}
84
            <pre>{{ agenda.event_display_template }}</pre>
85
          {% else %}
86
          {% trans "No event display template configured for this agenda." %}
87
          {% endif %}
53 88
        </li>
54
    </ul>
55
</div>
56
</div>
89
        <li>
90
          {% trans "Booking display template:" %}
91
          <pre>{{ agenda.get_booking_user_block_template }}</pre>
92
        </li>
93
      </ul>
94
      <div class="panel--buttons">
95
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
96
      </div>
97
    </div>
57 98

  
58
<div class="section">
59
<h3>{% trans "Booking check options" %}
60
    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
61
</h3>
62
<div>
63
    <ul>
64
    {% if has_check_types %}
99
    <div aria-labelledby="tab-booking-check-options" hidden="" id="panel-booking-check-options" role="tabpanel" tabindex="0">
100
      <ul>
101
        {% if has_check_types %}
65 102
        {% if agenda.check_type_group %}
66 103
        <li>{% trans "Check type group:" %} {{ agenda.check_type_group }}
67
            <ul>
68
                <li>{% trans "Absences:" %}
69
                    <ul>
70
                      {% for check_type in agenda.check_type_group.check_types.absences %}
71
                      <li>{{ check_type }}</li>
72
                      {% empty %}
73
                      <li>({% trans "No absence check type defined" %})</li>
74
                      {% endfor %}
75
                    </ul>
76
                </li>
77
                <li>{% trans "Presences:" %}
78
                    <ul>
79
                      {% for check_type in agenda.check_type_group.check_types.presences %}
80
                      <li>{{ check_type }}</li>
81
                      {% empty %}
82
                      <li>({% trans "No presence check type defined" %})</li>
83
                      {% endfor %}
84
                    </ul>
85
                </li>
86
            </ul>
104
          <ul>
105
            <li>{% trans "Absences:" %}
106
              <ul>
107
                {% for check_type in agenda.check_type_group.check_types.absences %}
108
                <li>{{ check_type }}</li>
109
                {% empty %}
110
                <li>({% trans "No absence check type defined" %})</li>
111
                {% endfor %}
112
              </ul>
113
            </li>
114
            <li>{% trans "Presences:" %}
115
              <ul>
116
                {% for check_type in agenda.check_type_group.check_types.presences %}
117
                <li>{{ check_type }}</li>
118
                {% empty %}
119
                <li>({% trans "No presence check type defined" %})</li>
120
                {% endfor %}
121
              </ul>
122
            </li>
123
          </ul>
87 124
        </li>
88 125
        {% else %}
89 126
        <li>{% trans "No check types configured for this agenda." %}</li>
90 127
        {% endif %}
91
    {% endif %}
128
        {% endif %}
92 129

  
93
    {% with agenda.get_booking_check_filters as check_filters %}
94
        {% if check_filters %}
95
        <li>{% trans "Filters:" %}
130
        {% with agenda.get_booking_check_filters as check_filters %}
131
          {% if check_filters %}
132
          <li>{% trans "Filters:" %}
96 133
            <ul>
97
                {% for key in check_filters %}
98
                <li>{{ key }}</li>
99
                {% endfor %}
134
              {% for key in check_filters %}
135
              <li>{{ key }}</li>
136
              {% endfor %}
100 137
            </ul>
101
        </li>
102
        {% else %}
103
        <li>{% trans "No filters configured for this agenda." %}</li>
104
        {% endif %}
105
    {% endwith %}
106

  
138
          </li>
139
          {% else %}
140
          <li>{% trans "No filters configured for this agenda." %}</li>
141
          {% endif %}
142
        {% endwith %}
107 143
        <li>{% trans "Automatically mark event as checked when all bookings have been checked:" %} {{ agenda.mark_event_checked_auto|yesno }}</li>
108 144
        <li>{% trans "Prevent the check of bookings when event was marked as checked:" %} {{ agenda.disable_check_update|yesno }}</li>
109
    </ul>
110
</div>
111
</div>
145
      </ul>
146
      <div class="panel--buttons">
147
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
148
      </div>
149
    </div>
112 150

  
113
{% if pricing_enabled %}
114
<div class="section">
115
<h3>{% trans "Pricing" context 'pricing' %}</h3>
116
<div>
117
  {% if agenda_pricings %}
118
  <ul class="objects-list single-links">
119
  {% for agenda_pricing in agenda_pricings %}
120
    <li><a href="{% url 'chrono-manager-agenda-pricing-detail' agenda.pk agenda_pricing.pk %}">{{ agenda_pricing.pricing }} ({{ agenda_pricing.date_start|date:'d/m/Y' }} - {{ agenda_pricing.date_end|date:'d/m/Y' }})</a></li>
121
  {% endfor %}
122
  </ul>
123
  {% else %}
124
  <div class="big-msg-info">
125
    {% blocktrans %}
126
    This agenda doesn't have any pricing defined yet. Click on the "New pricing" button in
127
    the top right of the page to add a first one.
128
    {% endblocktrans %}
129
  </div>
130
  {% endif %}
131
</div>
132
</div>
133
{% endif %}
134

  
135
<div class="section">
136
<h3>{% trans "Notifications" %}
137
<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-notifications-settings' pk=object.id %}">{% trans 'Configure' %}</a>
138
</h3>
139
<div>
140
{% for notification_type in object.notifications_settings.get_notification_types %}
141
{% if forloop.first %}<ul>{% endif %}
142
  <li>
143
  {% blocktrans trimmed with display_value=notification_type.display_value label=notification_type.label %}
144
  {{ label }}: {{ display_value }} will be notified.
145
  {% endblocktrans %}
146
  </li>
147
{% if forloop.last %}</ul>{% endif %}
148
{% empty %}
149
<p>{% trans "Notifications are disabled for this agenda." %}</p>
150
{% endfor %}
151
</div>
152
</div>
151
    {% if pricing_enabled %}
152
    <div aria-labelledby="tab-pricing" hidden="" id="panel-pricing" role="tabpanel" tabindex="0">
153
      {% if agenda_pricings %}
154
      <ul class="objects-list single-links">
155
      {% for agenda_pricing in agenda_pricings %}
156
        <li><a href="{% url 'chrono-manager-agenda-pricing-detail' agenda.pk agenda_pricing.pk %}">{{ agenda_pricing.pricing }} ({{ agenda_pricing.date_start|date:'d/m/Y' }} - {{ agenda_pricing.date_end|date:'d/m/Y' }})</a></li>
157
      {% endfor %}
158
      </ul>
159
      {% else %}
160
      <div class="big-msg-info">
161
        {% blocktrans %}
162
        This agenda doesn't have any pricing defined yet. Click on the "New pricing" button in
163
        the top right of the page to add a first one.
164
        {% endblocktrans %}
165
      </div>
166
      {% endif %}
167
    </div>
168
    {% endif %}
153 169

  
154
{% if has_recurring_events %}
155
<div class="section">
156
<h3>{% trans "Recurrence exceptions" %}
157
<a rel="popup" class="button" href="{% url 'chrono-manager-desk-add-import-time-period-exceptions' pk=desk.pk %}">{% trans 'Configure' %}</a>
158
</h3>
159
<div>
160
{% if object.recurrence_exceptions_report.events.exists %}
161
<div class="warningnotice">
162
<p>{% trans "The following events exist despite exceptions because they have active bookings:" %}</p>
163
<ul>
164
{% for event in object.recurrence_exceptions_report.events.all %}
165
<li><a href="{{ event.get_absolute_view_url }}">{{ event }}{% if event.label %} - {{ event.start_datetime|date:"DATETIME_FORMAT" }}{% endif %}</a></li>
166
{% endfor %}
167
</ul>
168
<p>{% trans "You can cancel them manually for this warning to go away, or wait until they are passed." %}</p>
169
</div>
170
{% endif %}
171
<ul class="objects-list single-links">
172
{% for exception in exceptions|slice:":5" %}
173
   <li><a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>
174
  {{ exception }}
175
  {% if not exception.read_only %}
176
  <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
177
  {% endif %}
178
{% endfor %}
179
{% if exceptions|length > 5 %}
180
<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>
181
{% endif %}
182
<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>
183
</ul>
184
</div>
185
</div>
186
{% endif %}
170
    <div aria-labelledby="tab-notifications" hidden="" id="panel-notifications" role="tabpanel" tabindex="0">
171
      {% for notification_type in object.notifications_settings.get_notification_types %}
172
      {% if forloop.first %}<ul>{% endif %}
173
        <li>
174
        {% blocktrans trimmed with display_value=notification_type.display_value label=notification_type.label %}
175
        {{ label }}: {{ display_value }} will be notified.
176
        {% endblocktrans %}
177
        </li>
178
      {% if forloop.last %}</ul>{% endif %}
179
      {% empty %}
180
        <p>{% trans "Notifications are disabled for this agenda." %}</p>
181
      {% endfor %}
182
      <div class="panel--buttons">
183
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-notifications-settings' pk=object.id %}">{% trans 'Configure' %}</a>
184
      </div>
185
    </div>
187 186

  
188 187
{% endblock %}
chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
26 26
  {% endif %}
27 27
{% endblock %}
28 28

  
29
{% block agenda-settings %}
29
{% block agenda-settings-extra-tab-buttons %}
30
    <button aria-controls="panel-meeting-types" aria-selected="true" id="tab-meeting-types" role="tab" tabindex="0">{% trans "Meeting Types" %}</button>
31
    {% if object.desk_simple_management %}
32
    <button aria-controls="panel-desks" aria-selected="false" id="tab-desks" role="tab" tabindex="-1">{% trans "Desks" %}</button>
33
    {% endif %}
34
    <button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Time Periods" %}</button>
35
    {% if has_resources %}
36
    <button aria-controls="panel-resources" aria-selected="false" id="tab-resources" role="tab" tabindex="-1">{% trans "Resources" %}</button>
37
    {% endif %}
38
    <button aria-controls="panel-display-options" aria-selected="false" id="tab-display-options" role="tab" tabindex="-1">{% trans "Display options" %}</button>
39
{% endblock %}
40

  
41
{% block agenda-settings-extra-tab-list %}
30 42

  
31
<div class="section">
32
<h3>{% trans 'Meeting Types' %}</h3>
33
<div>
34
{% if meeting_types %}
35
  <ul class="objects-list single-links">
36
    {% for meeting_type in meeting_types %}
37
    <li><a rel="popup" href="{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}">
38
        {{meeting_type.label}}
39
        <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
40
        <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
41
        </a>
42
        <a rel="popup" class="delete" href="{% url 'chrono-manager-meeting-type-delete' pk=meeting_type.id %}">{% trans "remove" %}</a>
43
    </li>
44
    {% endfor %}
45
  </ul>
46
{% else %}
47
<div class="big-msg-info">
48
  {% blocktrans %}
49
  This agenda doesn't have any meeting type yet. Click on the "New Meeting Type" button in
50
  the top right of the page to add a first one.
51
  {% endblocktrans %}
52
</div>
53
{% endif %}
54
</div>
55
</div>
43
    <div aria-labelledby="tab-meeting-types" id="panel-meeting-types" role="tabpanel" tabindex="0">
44
      {% if meeting_types %}
45
      <ul class="objects-list single-links">
46
        {% for meeting_type in meeting_types %}
47
        <li>
48
          <a rel="popup" href="{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}">
49
            {{meeting_type.label}}
50
            <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
51
            <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
52
          </a>
53
          <a rel="popup" class="delete" href="{% url 'chrono-manager-meeting-type-delete' pk=meeting_type.id %}">{% trans "remove" %}</a>
54
        </li>
55
        {% endfor %}
56
      </ul>
57
      {% else %}
58
      <div class="big-msg-info">
59
        {% blocktrans %}
60
        This agenda doesn't have any meeting type yet. Click on the "New Meeting Type" button in
61
        the top right of the page to add a first one.
62
        {% endblocktrans %}
63
      </div>
64
      {% endif %}
65
    </div>
56 66

  
57
{% if object.desk_simple_management %}
58
<div class="section">
59
<h3>{% trans 'Desks' %}</h3>
60
<div>
61
    <ul class="objects-list single-links">
67
    {% if object.desk_simple_management %}
68
    <div aria-labelledby="tab-desks" hidden="" id="panel-desks" role="tabpanel" tabindex="0">
69
      <ul class="objects-list single-links">
62 70
        {% for desk in object.prefetched_desks %}
63
            <li>
64
                <a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.pk %}">{{ desk.label }}</a>
65
                <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.pk %}">{% trans "remove" %}</a>
66
            </li>
71
          <li>
72
            <a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.pk %}">{{ desk.label }}</a>
73
            <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.pk %}">{% trans "remove" %}</a>
74
          </li>
67 75
        {% endfor %}
68
    </ul>
69
</div>
70
</div>
71
{% endif %}
76
      </ul>
77
    </div>
78
    {% endif %}
72 79

  
73
<div class="section">
74
<h3>{% trans 'Time Periods' %}</h3>
75
<div>
76
    {% if object.prefetched_desks %}
77
    <div class="timeperiods">
80
    <div aria-labelledby="tab-time-periods" hidden="" id="panel-time-periods" role="tabpanel" tabindex="0">
81
      {% if object.prefetched_desks %}
82
      <div class="timeperiods">
78 83
        {% for desk in object.prefetched_desks %}
79 84
        {% if not object.desk_simple_management or object.desk_simple_management and forloop.counter == 1 %}
80 85
        <div class="timeperiod">
81
            {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
82
            <ul class="objects-list single-links">
83
                {% if not object.desk_simple_management and object.prefetched_desks|length > 1 %}
84
                <li><a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.id %}">
85
                    <strong>{{ desk.label }}</strong>
86
                    </a>
87
                   <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.id %}">{% trans "remove" %}</a>
88
                </li>
89
                {% endif %}
90
                {% for time_period in desk.timeperiod_set.all %}
91
                <li><a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
92
                <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
93

  
94
                </li>
95
                {% endfor %}
96
                <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
97
                {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
98
                <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>
99
                {% for exception in desk.get_exceptions_within_two_weeks %}
100
                     <li><a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>
101
                    {{ exception }}
102
                    {% if not exception.read_only %}
103
                    <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
104
                    {% endif %}
105
                {% endfor %}
106
                {% if not desk.are_all_exceptions_displayed %}
107
                <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>
108
                {% endif %}
109
                <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
110
            </ul>
86
          {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
87
          <ul class="objects-list single-links">
88
            {% if not object.desk_simple_management and object.prefetched_desks|length > 1 %}
89
            <li>
90
              <a rel="popup" href="{% url 'chrono-manager-desk-edit' pk=desk.id %}">
91
                <strong>{{ desk.label }}</strong>
92
              </a>
93
              <a rel="popup" class="delete" href="{% url 'chrono-manager-desk-delete' pk=desk.id %}">{% trans "remove" %}</a>
94
            </li>
95
            {% endif %}
96
            {% for time_period in desk.timeperiod_set.all %}
97
            <li>
98
              <a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
99
              <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
100
            </li>
101
            {% endfor %}
102
            <li><a class="add" rel="popup" href="{{add_time_period_url}}">{% trans 'Add a time period' %}</a></li>
103
            {% url 'chrono-manager-agenda-add-time-period-exception' agenda_pk=object.pk pk=desk.pk as add_time_period_exception_url %}
104
            <li>
105
              <a><strong>{% trans 'Exceptions' %}</strong></a>
106
              <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>
107
            </li>
108
            {% for exception in desk.get_exceptions_within_two_weeks %}
109
            <li>
110
              <a rel="popup" {% if not exception.read_only %}href="{% url 'chrono-manager-time-period-exception-edit' pk=exception.pk %}"{% endif %}>{{ exception }}</a>
111
              {% if not exception.read_only %}
112
              <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-exception-delete' pk=exception.id %}">{% trans "remove" %}</a>
113
              {% endif %}
114
            </li>
115
            {% endfor %}
116
            {% if not desk.are_all_exceptions_displayed %}
117
            <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>
118
            {% endif %}
119
            <li><a class="add" rel="popup" href="{{add_time_period_exception_url}}">{% trans 'Add a time period exception' %}</a></li>
120
          </ul>
111 121
        </div>
112 122
        {% endif %}
113 123
        {% endfor %}
124
      </div>
125
      {% else %}
126
      <div class="big-msg-info">
127
        {% blocktrans %}
128
        This agenda doesn't have any desk yet. Click on the "New Desk" button in
129
        the top right of the page to add a first one.
130
        {% endblocktrans %}
131
      </div>
132
      {% endif %}
114 133
    </div>
115
    {% else %}
116
    <div class="big-msg-info">
117
    {% blocktrans %}
118
    This agenda doesn't have any desk yet. Click on the "New Desk" button in
119
    the top right of the page to add a first one.
120
    {% endblocktrans %}
121
    </div>
122
    {% endif %}
123
</div>
124
</div>
125 134

  
126
{% with object.resources.all as agenda_resources %}
127
{% if has_resources %}
128
<div class="section">
129
<h3>{% trans 'Resources' %}</h3>
130
<div>
131
{% if agenda_resources %}
132
  <ul class="objects-list single-links">
133
    {% for resource in agenda_resources %}
134
    <li>
135
        <a href="{% url 'chrono-manager-resource-view' pk=resource.pk %}">
135
    {% if has_resources %}
136
    <div aria-labelledby="tab-resources" hidden="" id="panel-resources" role="tabpanel" tabindex="0">
137
      {% with object.resources.all as agenda_resources %}
138
      {% if agenda_resources %}
139
      <ul class="objects-list single-links">
140
        {% for resource in agenda_resources %}
141
        <li>
142
          <a href="{% url 'chrono-manager-resource-view' pk=resource.pk %}">
136 143
            {{ resource.label }}
137 144
            <span class="identifier">[{% trans "identifier:" %} {{ resource.slug }}]</span>
138
        </a>
139
        <a rel="popup" class="delete" href="{% url 'chrono-manager-agenda-delete-resource' pk=object.pk resource_pk=resource.pk %}">{% trans "remove" %}</a>
140
    </li>
141
    {% endfor %}
142
  </ul>
143
{% else %}
144
<div class="big-msg-info">
145
  {% blocktrans %}
146
  This agenda doesn't have any resource yet. Click on the "Add resource" button in
147
  the top right of the page to add a first one.
148
  {% endblocktrans %}
149
</div>
150
{% endif %}
151
</div>
152
</div>
153
{% endif %}
154
{% endwith %}
145
          </a>
146
          <a rel="popup" class="delete" href="{% url 'chrono-manager-agenda-delete-resource' pk=object.pk resource_pk=resource.pk %}">{% trans "remove" %}</a>
147
        </li>
148
        {% endfor %}
149
      </ul>
150
      {% else %}
151
      <div class="big-msg-info">
152
        {% blocktrans %}
153
        This agenda doesn't have any resource yet. Click on the "Add resource" button in
154
        the top right of the page to add a first one.
155
        {% endblocktrans %}
156
      </div>
157
      {% endif %}
158
      {% endwith %}
159
    </div>
160
    {% endif %}
155 161

  
156
<div class="section">
157
<h3>{% trans "Display options" %}
158
    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
159
</h3>
160
<div>
161
    <ul>
162
    <div aria-labelledby="tab-display-options" hidden="" id="panel-display-options" role="tabpanel" tabindex="0">
163
      <ul>
162 164
        <li>
163
            {% trans "Booking display template:" %}
164
            <pre>{{ agenda.get_booking_user_block_template }}</pre>
165
          {% trans "Booking display template:" %}
166
          <pre>{{ agenda.get_booking_user_block_template }}</pre>
165 167
        </li>
166
    </ul>
167
</div>
168
</div>
168
      </ul>
169
      <div class="panel--buttons">
170
        <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-display-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
171
      </div>
172
    </div>
169 173

  
170 174
{% endblock %}
chrono/manager/templates/chrono/manager_virtual_agenda_settings.html
6 6
  <a rel="popup" href="{% url 'chrono-manager-agenda-add-virtual-member' pk=object.id %}">{% trans 'Include Agenda' %}</a>
7 7
{% endblock %}
8 8

  
9
{% block agenda-settings %}
9
{% block agenda-settings-extra-tab-buttons %}
10
    <button aria-controls="panel-agendas" aria-selected="true" id="tab-agendas" role="tab" tabindex="0">{% trans "Included Agendas" %}</button>
11
   {% if virtual_members %}
12
    <button aria-controls="panel-meeting-types" aria-selected="false" id="tab-meeting-types" role="tab" tabindex="-1">{% trans "Meeting Types" %}</button>
13
    {% endif %}
14
    <button aria-controls="panel-time-periods" aria-selected="false" id="tab-time-periods" role="tab" tabindex="-1">{% trans "Excluded Periods" %}</button>
15
{% endblock %}
10 16

  
11
<div class="section">
12
<h3>{% trans 'Included Agendas' %}</h3>
13
<div>
14
{% if virtual_members %}
15
  <ul class="objects-list single-links">
16
    {% for virtual_member, can_be_managed in virtual_members %}
17
    <li><a {% if can_be_managed %}href="{% url 'chrono-manager-agenda-settings' pk=virtual_member.real_agenda.id %}"{% endif %}>
18
        {{virtual_member.real_agenda.label}}
19
        </a>
20
        <a rel="popup" class="delete" href="{% url 'chrono-manager-virtual-member-delete' pk=virtual_member.pk %}">{% trans "remove" %}</a>
21
    </li>
22
    {% endfor %}
23
  </ul>
24
{% else %}
25
<div class="big-msg-info">
26
  {% blocktrans %}
27
  This virtual agenda doesn't include any agenda yet. Click on the "Include Agenda" button in
28
  the top right of the page to include a first one.
29
  {% endblocktrans %}
30
</div>
31
{% endif %}
32
</div>
33
</div>
17
{% block agenda-settings-extra-tab-list %}
34 18

  
35
{% if virtual_members %}
36
<div class="section">
37
<h3>{% trans 'Meeting Types' %}</h3>
38
<div>
39
{% if meeting_types %}
40
  <ul class="objects-list single-links">
41
    {% for meeting_type in meeting_types %}
42
    <li><a rel="popup" href="">
43
        {{meeting_type.label}}
44
        <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
45
        <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
46
        </a>
47
    </li>
48
    {% endfor %}
49
  </ul>
50
{% else %}
51
<div class="errornotice">
52
  {% blocktrans %}
53
  This virtual agenda doesn't have any meeting type.
54
  It is probably because its included agendas have incompatible meeting types
55
  and it makes this virtual agenda unusable.
56
  {% endblocktrans %}
57
</div>
58
{% endif %}
59
</div>
60
</div>
61
{% endif %}
19
    <div aria-labelledby="tab-agendas" id="panel-agendas" role="tabpanel" tabindex="0">
20
      {% if virtual_members %}
21
      <ul class="objects-list single-links">
22
        {% for virtual_member, can_be_managed in virtual_members %}
23
        <li>
24
          <a {% if can_be_managed %}href="{% url 'chrono-manager-agenda-settings' pk=virtual_member.real_agenda.id %}"{% endif %}>
25
            {{virtual_member.real_agenda.label}}
26
          </a>
27
          <a rel="popup" class="delete" href="{% url 'chrono-manager-virtual-member-delete' pk=virtual_member.pk %}">{% trans "remove" %}</a>
28
        </li>
29
        {% endfor %}
30
      </ul>
31
      {% else %}
32
      <div class="big-msg-info">
33
        {% blocktrans %}
34
        This virtual agenda doesn't include any agenda yet. Click on the "Include Agenda" button in
35
        the top right of the page to include a first one.
36
        {% endblocktrans %}
37
      </div>
38
      {% endif %}
39
    </div>
62 40

  
63
{% if agenda.excluded_timeperiods.count %}
64
<div class="section">
65
<h3>{% trans 'Excluded Periods' %}</h3>
66
<div>
67
  <ul class="objects-list single-links">
68
    {% for time_period in agenda.excluded_timeperiods.all %}
69
    <li><a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
70
      <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
71
    </li>
72
    {% endfor %}
73
  </ul>
74
</div>
75
</div>
76
{% endif %}
41
   {% if virtual_members %}
42
    <div aria-labelledby="tab-meeting-types" hidden="" id="panel-meeting-types" role="tabpanel" tabindex="0">
43
      {% if meeting_types %}
44
      <ul class="objects-list single-links">
45
        {% for meeting_type in meeting_types %}
46
        <li>
47
          <a rel="popup" href="">
48
            {{meeting_type.label}}
49
            <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
50
            <span class="identifier">[{% trans "identifier:" %} {{meeting_type.slug}}]</span>
51
          </a>
52
        </li>
53
        {% endfor %}
54
      </ul>
55
      {% else %}
56
      <div class="errornotice">
57
        {% blocktrans %}
58
        This virtual agenda doesn't have any meeting type.
59
        It is probably because its included agendas have incompatible meeting types
60
        and it makes this virtual agenda unusable.
61
        {% endblocktrans %}
62
      </div>
63
      {% endif %}
64
    </div>
65
    {% endif %}
66

  
67
    <div aria-labelledby="tab-time-periods" hidden="" id="panel-time-periods" role="tabpanel" tabindex="0">
68
      {% if agenda.excluded_timeperiods.count %}
69
      <ul class="objects-list single-links">
70
        {% for time_period in agenda.excluded_timeperiods.all %}
71
        <li><a rel="popup" href="{% url 'chrono-manager-time-period-edit' pk=time_period.id %}">{{ time_period }}</a>
72
          <a rel="popup" class="delete" href="{% url 'chrono-manager-time-period-delete' pk=time_period.id %}">{% trans "remove" %}</a>
73
        </li>
74
        {% endfor %}
75
      </ul>
76
      {% else %}
77
      <div class="big-msg-info">
78
        {% blocktrans %}
79
        This virtual agenda doesn't have any excluded period yet. Click on the "Add Excluded Period" button in
80
        the top right of the page to include a first one.
81
        {% endblocktrans %}
82
      </div>
83
      {% endif %}
84
    </div>
77 85

  
78
{% block agenda-reminder %}
79
{% endblock %}
80 86
{% endblock %}
tests/manager/test_all.py
2160 2160
    assert 'Delete' in resp.text
2161 2161
    assert 'Included Agendas' in resp.text
2162 2162
    assert 'Add Excluded Period' in resp.text
2163
    assert 'Excluded Periods' in resp.text
2164
    assert "This virtual agenda doesn't have any excluded period yet" in resp.text
2163 2165
    assert "This virtual agenda doesn't include any agenda yet" in resp.text
2164 2166
    # No meeting types yet
2165 2167
    assert 'Meeting Types' not in resp.text
2166
    # No absence yet
2167
    assert 'Excluded Periods' not in resp.text
2168 2168

  
2169 2169

  
2170 2170
def test_virtual_agenda_settings(app, admin_user):
tests/manager/test_exception.py
94 94
        hour=16
95 95
    ).strftime(dt_format)
96 96
    # add an exception beyond 2 weeks and make sure it isn't listed
97
    resp = resp.click('Add a time period exception', index=1)
97
    resp = resp.click('Add a time period exception', index=0)
98 98
    future = tomorrow + datetime.timedelta(days=15)
99 99
    resp.form['label'] = 'Exception 2'
100 100
    resp.form['start_datetime_0'] = future.strftime('%Y-%m-%d')
101
-