Merged in [19841] from jennifer@painless-security.com:
Link to the timeslot editor when meeting has no timeslots. Fixes #3511.
- Legacy-Id: 19852
Note: SVN reference [19841] has been migrated to Git commit 64e904804d
This commit is contained in:
commit
6f682c313c
|
@ -1677,6 +1677,23 @@ class EditMeetingScheduleTests(TestCase):
|
|||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(self._decode_json_response(r)['success'])
|
||||
|
||||
def test_editor_with_no_timeslots(self):
|
||||
"""Schedule editor should not crash when there are no timeslots"""
|
||||
meeting = MeetingFactory(
|
||||
type_id='ietf',
|
||||
date=datetime.date.today() + datetime.timedelta(days=7),
|
||||
populate_schedule=False,
|
||||
)
|
||||
meeting.schedule = ScheduleFactory(meeting=meeting)
|
||||
meeting.save()
|
||||
SessionFactory(meeting=meeting, add_to_schedule=False)
|
||||
self.assertEqual(meeting.timeslot_set.count(), 0, 'Test problem - meeting should not have any timeslots')
|
||||
url = urlreverse('ietf.meeting.views.edit_meeting_schedule', kwargs={'num': meeting.number})
|
||||
self.assertTrue(self.client.login(username='secretary', password='secretary+password'))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertContains(r, 'No timeslots exist')
|
||||
self.assertContains(r, urlreverse('ietf.meeting.views.edit_timeslots', kwargs={'num': meeting.number}))
|
||||
|
||||
|
||||
class EditTimeslotsTests(TestCase):
|
||||
|
|
|
@ -506,8 +506,8 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None):
|
|||
min_duration = min(t.duration for t in timeslots_qs)
|
||||
max_duration = max(t.duration for t in timeslots_qs)
|
||||
else:
|
||||
min_duration = 1
|
||||
max_duration = 2
|
||||
min_duration = datetime.timedelta(minutes=30)
|
||||
max_duration = datetime.timedelta(minutes=120)
|
||||
|
||||
def timedelta_to_css_ems(timedelta):
|
||||
# we scale the session and slots a bit according to their
|
||||
|
|
|
@ -75,96 +75,106 @@
|
|||
{% endif %}
|
||||
</p>
|
||||
|
||||
<div class="edit-grid {% if not can_edit %}read-only{% endif %}">
|
||||
|
||||
{# using the same markup in both room labels and the actual days ensures they are aligned #}
|
||||
<div class="room-label-column">
|
||||
{% for day_data in days.values %}
|
||||
<div class="day">
|
||||
<div class="day-label">
|
||||
<strong> </strong><br>
|
||||
|
||||
</div>
|
||||
|
||||
{% for rgroup in day_data %}
|
||||
<div class="room-group">
|
||||
<div class="time-header"><div class="time-label"></div></div>
|
||||
{% for room_data in rgroup %}{% with room_data.room as room %}
|
||||
<div class="timeslots">
|
||||
<div class="room-name">
|
||||
<strong>{{ room.name }}</strong><br>
|
||||
{% if room.capacity %}{{ room.capacity }} <i class="fa fa-user-o"></i>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}{% endfor %}
|
||||
{% if timeslot_groups|length == 0 %}
|
||||
<p>
|
||||
No timeslots exist for this meeting yet.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{% url "ietf.meeting.views.edit_timeslots" num=meeting.number %}">
|
||||
Edit timeslots.
|
||||
</a>
|
||||
</p>
|
||||
{% else %}
|
||||
<div class="edit-grid {% if not can_edit %}read-only{% endif %}">
|
||||
{# using the same markup in both room labels and the actual days ensures they are aligned #}
|
||||
<div class="room-label-column">
|
||||
{% for day_data in days.values %}
|
||||
<div class="day">
|
||||
<div class="day-label">
|
||||
<strong> </strong><br>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="day-flow">
|
||||
{% for day, day_data in days.items %}
|
||||
<div class="day">
|
||||
<div class="day-label">
|
||||
<strong>{{ day|date:"l" }}</strong>
|
||||
<i class="fa fa-exchange swap-days"
|
||||
data-dayid="{{ day.isoformat }}"
|
||||
data-start="{{ day.isoformat }}"></i>
|
||||
<br>
|
||||
{{ day|date:"N j, Y" }}
|
||||
</div>
|
||||
|
||||
{% for rgroup in day_data %}
|
||||
<div class="room-group"
|
||||
data-index="{{ forloop.counter0 }}"
|
||||
data-rooms="{% for r in rgroup %}{{ r.room.pk }}{% if not forloop.last %},{% endif %}{% endfor %}">
|
||||
<div class="time-header">
|
||||
{# All rooms in a group have same timeslots; grab the first for the labels #}
|
||||
{% for t in rgroup.0.timeslots %}
|
||||
<div class="time-label" style="width: {{ t.layout_width }}rem">
|
||||
<span>
|
||||
{{ t.time|date:"G:i" }} - {{ t.end_time|date:"G:i" }}
|
||||
<i class="fa fa-exchange swap-timeslot-col"
|
||||
data-origin-label="{{ day|date:"l, N j" }}, {{ t.time|date:"G:i" }}-{{ t.end_time|date:"G:i" }}"
|
||||
data-start="{{ t.utc_start_time.isoformat }}"
|
||||
data-timeslot-pk="{{ t.pk }}"></i>
|
||||
</span>
|
||||
{% for rgroup in day_data %}
|
||||
<div class="room-group">
|
||||
<div class="time-header"><div class="time-label"></div></div>
|
||||
{% for room_data in rgroup %}{% with room_data.room as room %}
|
||||
<div class="timeslots">
|
||||
<div class="room-name">
|
||||
<strong>{{ room.name }}</strong><br>
|
||||
{% if room.capacity %}{{ room.capacity }} <i class="fa fa-user-o"></i>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endwith %}{% endfor %}
|
||||
</div>
|
||||
{% for room_data in rgroup %}{% with room_data.room as room %}
|
||||
<div class="timeslots" data-roomcapacity="{{ room.capacity }}">
|
||||
{% for t in room_data.timeslots %}
|
||||
<div id="timeslot{{ t.pk }}"
|
||||
class="timeslot {{ t.start_end_group }}"
|
||||
data-start="{{ t.utc_start_time.isoformat }}"
|
||||
data-end="{{ t.utc_end_time.isoformat }}"
|
||||
data-duration="{{ t.duration.total_seconds }}"
|
||||
data-scheduledatlabel="{{ t.time|date:"l G:i" }}-{{ t.end_time|date:"G:i" }}"
|
||||
data-type="{{ t.type.slug }}"
|
||||
style="width: {{ t.layout_width }}rem;">
|
||||
<div class="time-label">
|
||||
<div class="past-flag"> {# blank div keeps time centered vertically #}</div>
|
||||
<div>{{ t.time|date:"G:i" }} - {{ t.end_time|date:"G:i" }}</div>
|
||||
<div class="past-flag">Past</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="drop-target">
|
||||
{% for assignment, session in t.session_assignments %}
|
||||
{% include "meeting/edit_meeting_schedule_session.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="day-flow">
|
||||
{% for day, day_data in days.items %}
|
||||
<div class="day">
|
||||
<div class="day-label">
|
||||
<strong>{{ day|date:"l" }}</strong>
|
||||
<i class="fa fa-exchange swap-days"
|
||||
data-dayid="{{ day.isoformat }}"
|
||||
data-start="{{ day.isoformat }}"></i>
|
||||
<br>
|
||||
{{ day|date:"N j, Y" }}
|
||||
</div>
|
||||
|
||||
{% for rgroup in day_data %}
|
||||
<div class="room-group"
|
||||
data-index="{{ forloop.counter0 }}"
|
||||
data-rooms="{% for r in rgroup %}{{ r.room.pk }}{% if not forloop.last %},{% endif %}{% endfor %}">
|
||||
<div class="time-header">
|
||||
{# All rooms in a group have same timeslots; grab the first for the labels #}
|
||||
{% for t in rgroup.0.timeslots %}
|
||||
<div class="time-label" style="width: {{ t.layout_width }}rem">
|
||||
<span>
|
||||
{{ t.time|date:"G:i" }} - {{ t.end_time|date:"G:i" }}
|
||||
<i class="fa fa-exchange swap-timeslot-col"
|
||||
data-origin-label="{{ day|date:"l, N j" }}, {{ t.time|date:"G:i" }}-{{ t.end_time|date:"G:i" }}"
|
||||
data-start="{{ t.utc_start_time.isoformat }}"
|
||||
data-timeslot-pk="{{ t.pk }}"></i>
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endwith %}{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for room_data in rgroup %}{% with room_data.room as room %}
|
||||
<div class="timeslots" data-roomcapacity="{{ room.capacity }}">
|
||||
{% for t in room_data.timeslots %}
|
||||
<div id="timeslot{{ t.pk }}"
|
||||
class="timeslot {{ t.start_end_group }}"
|
||||
data-start="{{ t.utc_start_time.isoformat }}"
|
||||
data-end="{{ t.utc_end_time.isoformat }}"
|
||||
data-duration="{{ t.duration.total_seconds }}"
|
||||
data-scheduledatlabel="{{ t.time|date:"l G:i" }}-{{ t.end_time|date:"G:i" }}"
|
||||
data-type="{{ t.type.slug }}"
|
||||
style="width: {{ t.layout_width }}rem;">
|
||||
<div class="time-label">
|
||||
<div class="past-flag"> {# blank div keeps time centered vertically #}</div>
|
||||
<div>{{ t.time|date:"G:i" }} - {{ t.end_time|date:"G:i" }}</div>
|
||||
<div class="past-flag">Past</div>
|
||||
</div>
|
||||
|
||||
<div class="drop-target">
|
||||
{% for assignment, session in t.session_assignments %}
|
||||
{% include "meeting/edit_meeting_schedule_session.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endwith %}{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="scheduling-panel">
|
||||
<div class="unassigned-container">
|
||||
|
|
Loading…
Reference in a new issue