manager: display opening hours in background (#21244)

This commit is contained in:
Frédéric Péters 2018-01-18 17:37:43 +01:00
parent 2a5e6a95b2
commit 7d829d3081
4 changed files with 49 additions and 18 deletions

View File

@ -122,17 +122,26 @@ $dayview-column-width: 14vw;
}
.dayview tbody td div {
z-index: 1;
box-sizing: border-box;
padding: 1ex;
background: #eef;
position: absolute;
width: calc(#{$dayview-column-width} - 2ex);
border: 1px solid #aaa;
overflow: hidden;
&:hover {
&.opening-hours {
z-index: 1;
background: #00ff00;
opacity: 0.1;
left: 0.5ex;
width: calc(#{$dayview-column-width} - 1ex);
}
&.booking {
background: #eef;
width: calc(#{$dayview-column-width} - 2ex);
border: 1px solid #aaa;
z-index: 2;
height: auto !important;
&:hover {
z-index: 3;
height: auto !important;
}
}
}

View File

@ -41,8 +41,18 @@
<th>{{ period|date:"TIME_FORMAT" }}</th>
{% for desk_info in desk_infos %}
<td>
{% if forloop.parentloop.first %}
{# opening hours on the first row #}
{% for slot in desk_info.opening_hours %}
<div class="opening-hours"
style="height: {{ slot.css_height }}%; top: {{ slot.css_top }}%;"
>{{slot.begin}} {{slot.end}}</div>
{% endfor %}
{% endif %}
{% for booking in desk_info.bookings %}
<div class="booked"
<div class="booking"
style="height: {{ booking.css_height }}%; min-height: {{ booking.css_height }}%; top: {{ booking.css_top }}%;"
><span class="start-time">{{booking.event.start_datetime|date:"TIME_FORMAT"}}</span>
<a {% if booking.backoffice_url %}href="{{booking.backoffice_url}}"{% endif %}

View File

@ -23,7 +23,7 @@ from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Q
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.timezone import now, make_aware
from django.utils.timezone import localtime, now, make_aware
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext
from django.utils.encoding import force_text
@ -211,6 +211,7 @@ class AgendaDayView(DayArchiveView):
interval = datetime.timedelta(minutes=60)
current_date = self.date.replace(hour=min_timeperiod.hour, minute=0)
start_date = current_date
if max_timeperiod.minute == 0:
max_date = self.date.replace(hour=max_timeperiod.hour, minute=0)
else:
@ -219,12 +220,23 @@ class AgendaDayView(DayArchiveView):
desks = self.agenda.desk_set.all()
first = True
while current_date < max_date:
# for each timeslot return the timeslot date and a list of per-desk
# bookings
infos = [] # various infos, for each desk
for desk in desks:
bookings = [] # bookings for this desk
info = {'desk': desk}
if first:
# use first row to include opening hours
info['opening_hours'] = opening_hours = []
for opening_hour in desk.get_opening_hours(current_date.date()):
opening_hours.append({
'css_top': 100 * (opening_hour.begin - start_date).seconds / 3600,
'css_height': 100 * (opening_hour.end - opening_hour.begin).seconds / 3600,
})
infos.append(info)
info['bookings'] = bookings = [] # bookings for this desk
finish_datetime = current_date + interval
for event in [x for x in self.object_list if x.desk_id == desk.id and
x.start_datetime >= current_date and x.start_datetime < finish_datetime]:
@ -234,13 +246,9 @@ class AgendaDayView(DayArchiveView):
booking.css_height = int(100 * event.meeting_type.duration / 60)
bookings.append(booking)
infos.append({
'bookings': bookings,
'desk': desk,
})
yield current_date, infos
current_date += interval
first = False
agenda_day_view = AgendaDayView.as_view()

View File

@ -1198,7 +1198,7 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
timeperiod.save()
resp = app.get('/manage/agendas/%s/' % agenda.id, status=302).follow()
assert not 'No opening hours this day.' in resp.body
assert not 'div class="booked' in resp.body
assert not 'div class="booking' in resp.body
assert resp.body.count('<tr') == 9 # 10->18 (not included)
timeperiod.end_time = datetime.time(18, 30) # end during an hour
@ -1206,6 +1206,10 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
resp = app.get('/manage/agendas/%s/' % agenda.id, status=302).follow()
assert resp.body.count('<tr') == 10 # 10->18 (included)
# check opening hours cells
assert '<div class="opening-hours"' in resp.body
assert 'style="height: 850%; top: 0%;"' in resp.body
# book some slots
app.reset()
app.authorization = ('Basic', ('john.doe', 'password'))
@ -1221,7 +1225,7 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
date = Booking.objects.all()[0].event.start_datetime
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (
agenda.id, date.year, date.month, date.day))
assert resp.body.count('div class="booked') == 2
assert resp.body.count('div class="booking') == 2
assert 'hourspan-2' in resp.body # table CSS class
assert 'height: 50%; top: 0%;' in resp.body # booking cells
@ -1231,7 +1235,7 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
meetingtype.save()
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (
agenda.id, date.year, date.month, date.day))
assert resp.body.count('div class="booked') == 2
assert resp.body.count('div class="booking') == 2
assert 'hourspan-4' in resp.body # table CSS class
# cancel a booking
@ -1245,7 +1249,7 @@ def test_agenda_day_view(app, admin_user, manager_user, api_user):
login(app)
resp = app.get('/manage/agendas/%s/%d/%d/%d/' % (
agenda.id, date.year, date.month, date.day))
assert resp.body.count('div class="booked') == 1
assert resp.body.count('div class="booking') == 1
# wrong type
agenda2 = Agenda(label=u'Foo bar')