fix: miscellaneous tz fixes (#4481)
* fix: use meeting timezone for date comparison in agenda.html * fix: use meeting timezone in interim_meeting_cancellation_notice.txt * fix: use meeting timezone in interim_session_cancellation_notice.txt * fix: use meeting timezone for secr misc sessions tab * fix: use meeting tz for editing misc sessions * fix: handle times with day outside usual choices in secr app * fix: handle TZ correctly for reg sessions and timeslots in secr app * fix: handle timezone in session_schedule_notification.txt * fix: fix broken references in interim session cancellation template * test: use meeting timezone as element id for meeting/timeslot editing
This commit is contained in:
parent
cabb82efec
commit
fe7fc4b871
|
@ -271,14 +271,32 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
# modal_open.click()
|
||||
|
||||
self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal").is_displayed())
|
||||
self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal [value=\"{}\"]".format("ts-group-{}-{}".format(slot2.time.strftime("%Y%m%d-%H%M"), int(slot2.duration.total_seconds() / 60)))).click()
|
||||
self.driver.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
"#timeslot-group-toggles-modal [value=\"{}\"]".format(
|
||||
"ts-group-{}-{}".format(
|
||||
slot2.time.astimezone(slot2.tz()).strftime("%Y%m%d-%H%M"),
|
||||
int(slot2.duration.total_seconds() / 60),
|
||||
),
|
||||
),
|
||||
).click()
|
||||
self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal [data-bs-dismiss=\"modal\"]").click()
|
||||
self.assertTrue(not self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal").is_displayed())
|
||||
|
||||
# swap days
|
||||
self.driver.find_element(By.CSS_SELECTOR, ".day .swap-days[data-dayid=\"{}\"]".format(slot4.time.date().isoformat())).click()
|
||||
self.driver.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
".day .swap-days[data-dayid=\"{}\"]".format(
|
||||
slot4.time.astimezone(slot4.tz()).date().isoformat(),
|
||||
),
|
||||
).click()
|
||||
self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, "#swap-days-modal").is_displayed())
|
||||
self.driver.find_element(By.CSS_SELECTOR, "#swap-days-modal input[name=\"target_day\"][value=\"{}\"]".format(slot1.time.date().isoformat())).click()
|
||||
self.driver.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
"#swap-days-modal input[name=\"target_day\"][value=\"{}\"]".format(
|
||||
slot1.time.astimezone(slot1.tz()).date().isoformat(),
|
||||
),
|
||||
).click()
|
||||
self.driver.find_element(By.CSS_SELECTOR, "#swap-days-modal button[type=\"submit\"]").click()
|
||||
|
||||
self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot4.pk, s1.pk)),
|
||||
|
@ -430,21 +448,24 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
|
||||
past_swap_days_buttons = self.driver.find_elements(By.CSS_SELECTOR,
|
||||
','.join(
|
||||
'.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in past_timeslots
|
||||
'.swap-days[data-start="{}"]'.format(ts.time.astimezone(ts.tz()).date().isoformat())
|
||||
for ts in past_timeslots
|
||||
)
|
||||
)
|
||||
self.assertEqual(len(past_swap_days_buttons), len(past_timeslots), 'Missing past swap days buttons')
|
||||
|
||||
future_swap_days_buttons = self.driver.find_elements(By.CSS_SELECTOR,
|
||||
','.join(
|
||||
'.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in future_timeslots
|
||||
'.swap-days[data-start="{}"]'.format(ts.time.astimezone(ts.tz()).date().isoformat())
|
||||
for ts in future_timeslots
|
||||
)
|
||||
)
|
||||
self.assertEqual(len(future_swap_days_buttons), len(future_timeslots), 'Missing future swap days buttons')
|
||||
|
||||
now_swap_days_buttons = self.driver.find_elements(By.CSS_SELECTOR,
|
||||
','.join(
|
||||
'.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in now_timeslots
|
||||
'.swap-days[data-start="{}"]'.format(ts.time.astimezone(ts.tz()).date().isoformat())
|
||||
for ts in now_timeslots
|
||||
)
|
||||
)
|
||||
# only one "now" button because both sessions are on the same day
|
||||
|
@ -495,7 +516,8 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
self.assertFalse(
|
||||
any(radio.is_enabled()
|
||||
for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
|
||||
'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in past_timeslots)
|
||||
'input[name="target_day"][value="{}"]'.format(ts.time.astimezone(ts.tz()).date().isoformat())
|
||||
for ts in past_timeslots)
|
||||
)),
|
||||
'Past day is enabled in swap-days modal for official schedule',
|
||||
)
|
||||
|
@ -504,14 +526,16 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
self.assertTrue(
|
||||
all(radio.is_enabled()
|
||||
for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
|
||||
'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in enabled_timeslots)
|
||||
'input[name="target_day"][value="{}"]'.format(ts.time.astimezone(ts.tz()).date().isoformat())
|
||||
for ts in enabled_timeslots)
|
||||
)),
|
||||
'Future day is not enabled in swap-days modal for official schedule',
|
||||
)
|
||||
self.assertFalse(
|
||||
any(radio.is_enabled()
|
||||
for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
|
||||
'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in now_timeslots)
|
||||
'input[name="target_day"][value="{}"]'.format(ts.time.astimezone(ts.tz()).date().isoformat())
|
||||
for ts in now_timeslots)
|
||||
)),
|
||||
'"Now" day is enabled in swap-days modal for official schedule',
|
||||
)
|
||||
|
|
|
@ -1577,7 +1577,7 @@ def agenda(request, num=None, name=None, base=None, ext=None, owner=None, utc=""
|
|||
"updated": updated,
|
||||
"filter_categories": filter_organizer.get_filter_categories(),
|
||||
"non_area_keywords": filter_organizer.get_non_area_keywords(),
|
||||
"now": timezone.now().astimezone(pytz.utc),
|
||||
"now": timezone.now().astimezone(meeting.tz()),
|
||||
"display_timezone": display_timezone,
|
||||
"is_current_meeting": is_current_meeting,
|
||||
"use_codimd": True if meeting.date>=settings.MEETING_USES_CODIMD_DATE else False,
|
||||
|
|
|
@ -166,6 +166,15 @@ class TimeSlotForm(forms.Form):
|
|||
for n in range(-self.meeting.days, self.meeting.days):
|
||||
date = start + datetime.timedelta(days=n)
|
||||
choices.append((n, date.strftime("%a %b %d")))
|
||||
# make sure the choices include the initial day
|
||||
if self.initial and 'day' in self.initial:
|
||||
day = self.initial['day']
|
||||
date = start + datetime.timedelta(days=day)
|
||||
datestr = date.strftime("%a %b %d")
|
||||
if day < -self.meeting.days:
|
||||
choices.insert(0, (day, datestr))
|
||||
elif day >= self.meeting.days:
|
||||
choices.append((day, datestr))
|
||||
return choices
|
||||
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ def misc_session_edit(request, meeting_id, schedule_name, slot_id):
|
|||
'name':session.name,
|
||||
'short':session.short,
|
||||
'day':delta.days,
|
||||
'time':slot.time.strftime('%H:%M'),
|
||||
'time':slot.time.astimezone(meeting.tz()).strftime('%H:%M'),
|
||||
'duration':duration_string(slot.duration),
|
||||
'show_location':slot.show_location,
|
||||
'purpose': session.purpose,
|
||||
|
@ -813,13 +813,20 @@ def times_edit(request, meeting_id, schedule_name, time):
|
|||
parts = [ int(x) for x in time.split(':') ]
|
||||
dtime = make_aware(datetime.datetime(*parts), meeting.tz())
|
||||
timeslots = TimeSlot.objects.filter(meeting=meeting,time=dtime)
|
||||
day = (dtime.date() - meeting.date) // datetime.timedelta(days=1)
|
||||
initial = {'day': day,
|
||||
'time': dtime.strftime('%H:%M'),
|
||||
'duration': timeslots.first().duration,
|
||||
'name': timeslots.first().name}
|
||||
|
||||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit', '')
|
||||
if button_text == 'Cancel':
|
||||
return redirect('ietf.secr.meetings.views.times', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
form = TimeSlotForm(request.POST, meeting=meeting)
|
||||
# Pass "initial" even for a POST so the choices initialize correctly if day is outside
|
||||
# the standard set of options. See TimeSlotForm.get_day_choices().
|
||||
form = TimeSlotForm(request.POST, initial=initial, meeting=meeting)
|
||||
if form.is_valid():
|
||||
day = form.cleaned_data['day']
|
||||
time = get_timeslot_time(form, meeting)
|
||||
|
@ -838,13 +845,6 @@ def times_edit(request, meeting_id, schedule_name, time):
|
|||
else:
|
||||
# we need to pass the session to the form in order to disallow changing
|
||||
# of group after materials have been uploaded
|
||||
day = dtime.strftime('%w')
|
||||
if day == 6:
|
||||
day = -1
|
||||
initial = {'day':day,
|
||||
'time':dtime.strftime('%H:%M'),
|
||||
'duration':timeslots.first().duration,
|
||||
'name':timeslots.first().name}
|
||||
form = TimeSlotForm(initial=initial, meeting=meeting)
|
||||
|
||||
return render(request, 'meetings/times_edit.html', {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "meetings/base_rooms_times.html" %}
|
||||
{% load agenda_custom_tags %}
|
||||
{% load agenda_custom_tags tz %}
|
||||
{% block subsection %}
|
||||
|
||||
{% timezone meeting.time_zone %}
|
||||
<div class="module">
|
||||
<h2>TimeSlots</h2>
|
||||
|
||||
|
@ -73,7 +73,7 @@
|
|||
|
||||
</div> <!-- module -->
|
||||
|
||||
|
||||
{% endtimezone %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load staticfiles tz %}
|
||||
|
||||
{% block title %}Meetings{% endblock %}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
<form id="meetings-schedule-form" method="post">{% csrf_token %}
|
||||
<div class="inline-related{% if forloop.last %} last-related{% endif %}">
|
||||
<table class="full-width amstable">
|
||||
<table class="full-width amstable">{% timezone meeting.time_zone %}
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Day:</th>
|
||||
|
@ -40,7 +40,7 @@
|
|||
<!-- [html-validate-disable-block element-required-attributes -- FIXME: as_table renders without scope] -->
|
||||
{{ form.as_table }}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endtimezone %}</table>
|
||||
</div> <!-- inline-related -->
|
||||
|
||||
<div class="button-group">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Dear {{ to_name }},
|
||||
{% load tz %}{% timezone meeting.time_zone %}Dear {{ to_name }},
|
||||
|
||||
The session(s) that you have requested have been scheduled.
|
||||
Below is the scheduled session information followed by
|
||||
|
@ -16,4 +16,4 @@ iCalendar: {{ baseurl }}{% url "ietf.meeting.views.agenda_ical" num=meeting.numb
|
|||
|
||||
Request Information:
|
||||
|
||||
{% include "includes/session_info.txt" %}
|
||||
{% include "includes/session_info.txt" %}{% endtimezone %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "meetings/base_rooms_times.html" %}
|
||||
{% load django_bootstrap5 %}
|
||||
{% load django_bootstrap5 tz %}
|
||||
|
||||
{% block subsection %}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody>{% timezone meeting.time_zone %}
|
||||
{% for session in sessions %}
|
||||
<tr>
|
||||
<td>{{ session.group.acronym }}</td>
|
||||
|
@ -46,7 +46,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endtimezone %}</tbody>
|
||||
</table>
|
||||
</div> <!-- module -->
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "meetings/base_rooms_times.html" %}
|
||||
|
||||
{% load tz %}
|
||||
{% block subsection %}
|
||||
|
||||
<div class="module">
|
||||
|
@ -16,7 +16,7 @@
|
|||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody>{% timezone meeting.time_zone %}
|
||||
{% for item in times %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td>{{ item.time|date:"D M d" }}</td>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<td><a href="{% url "ietf.secr.meetings.views.times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Delete</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endtimezone %}</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<h3>No timeslots exist for this meeting. Add rooms with the "duplicate timeslots" option enabled to copy timeslots from the last meeting.</h3>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{% load ams_filters %}
|
||||
{% load ams_filters tz %}{% timezone meeting.time_zone %}
|
||||
The {{ group.name }} ({{ group.acronym }}) {% if not meeting.city %}virtual {% endif %}{% if is_multi_day %}multi-day {% endif %}
|
||||
interim meeting for {{ meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ meeting.time_zone }}
|
||||
has been cancelled.
|
||||
|
||||
{{ meeting.session_set.0.agenda_note }}
|
||||
|
||||
{% endtimezone %}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load ams_filters %}
|
||||
{% load ams_filters tz %}{% timezone session.meeting.time_zone %}
|
||||
{% if session.name %}The "{{ session.name }}"{% else %}A{% endif %} session of the {{ group.name }} ({{ group.acronym }}) {% if not session.meeting.city %}virtual {% endif %}{% if is_multi_day %}multi-day {% endif %}
|
||||
interim meeting has been cancelled. This session had been scheduled for {{ meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ meeting.time_zone }}.
|
||||
interim meeting has been cancelled. This session had been scheduled for {{ session.meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ session.meeting.time_zone }}.
|
||||
|
||||
{{ session.agenda_note }}
|
||||
|
||||
{% endtimezone %}
|
||||
|
||||
|
|
Loading…
Reference in a new issue