manager: update partial bookings html & css (#78728)
gitea/chrono/pipeline/head This commit looks good
Details
gitea/chrono/pipeline/head This commit looks good
Details
This commit is contained in:
parent
b615c57bad
commit
00ad7b0747
|
@ -598,10 +598,94 @@ div#appbar a.active {
|
|||
color: white;
|
||||
}
|
||||
|
||||
table.partial-bookings {
|
||||
border-spacing: 0;
|
||||
td.hour-cell {
|
||||
outline: solid 1px;
|
||||
// Partial booking view
|
||||
.partial-booking {
|
||||
--registrant-name-width: 15rem;
|
||||
--zebra-color: hsla(0,0%,0%,0.05);
|
||||
--separator-color: white;
|
||||
--separator-size: 2px;
|
||||
|
||||
position: relative;
|
||||
background: white;
|
||||
padding: 0.5rem;
|
||||
|
||||
&--hours-list {
|
||||
background: white;
|
||||
position: sticky;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--nb-hours), 1fr);
|
||||
font-size: 80%;
|
||||
@media (min-width: 761px) {
|
||||
padding-left: var(--registrant-name-width);
|
||||
}
|
||||
}
|
||||
&--hour {
|
||||
text-align: center;
|
||||
transform: translateX(-50%);
|
||||
|
||||
&:first-child {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
&--registrant-items {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
&--registrant {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
&:nth-child(odd) {
|
||||
background-color: var(--zebra-color);
|
||||
}
|
||||
&:nth-child(even) {
|
||||
--separator-color: var(--zebra-color);
|
||||
}
|
||||
.registrant {
|
||||
&--name {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: .66rem;
|
||||
font-size: 130%;
|
||||
color: #505050;
|
||||
font-weight: normal;
|
||||
@media (min-width: 761px) {
|
||||
flex: 0 0 var(--registrant-name-width);
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
&--datas {
|
||||
box-sizing: border-box;
|
||||
flex: 1 0 100%;
|
||||
@media (min-width: 761px) {
|
||||
flex-basis: auto;
|
||||
}
|
||||
background: linear-gradient(
|
||||
to left,
|
||||
var(--separator-color) var(--separator-size),
|
||||
transparent var(--separator-size),
|
||||
transparent 100%
|
||||
);
|
||||
background-size: calc(100% / var(--nb-hours)) 100%;
|
||||
@media (min-width: 761px) {
|
||||
border-left: var(--separator-size) solid var(--separator-color);
|
||||
}
|
||||
}
|
||||
&--bar-container {
|
||||
position: relative;
|
||||
padding: .33rem 0;
|
||||
}
|
||||
&--bar {
|
||||
--background: #1066bc;
|
||||
--color: white;
|
||||
box-sizing: border-box;
|
||||
margin: 0.33rem 0;
|
||||
position: relative;
|
||||
padding: 0.33em 0.66em;
|
||||
background-color: var(--background);
|
||||
color: var(--color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,36 +8,37 @@
|
|||
<p>{% trans "No opening hours this day." %}</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<table class="agenda-table partial-bookings">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
{% for hour in hours %}
|
||||
<th>{{ hour|date:"TIME_FORMAT" }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for user, bookings in bookings_by_user.items %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<th>{{ bookings.0.get_user_block }}</th>
|
||||
{% for _ in hours %}
|
||||
<td class="hour-cell">
|
||||
{% if forloop.first %}
|
||||
{% for booking in bookings %}
|
||||
<div class="booking"
|
||||
style="left: {{ booking.css_left }}%; width: {{ booking.css_width }}%;"
|
||||
>{{ booking.start_time }} - {{ booking.end_time }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
<div class="partial-booking" style="--nb-hours: {{ hours|length }}">
|
||||
<div class="partial-booking--hours-list" aria-hidden="true">
|
||||
{% for hour in hours %}
|
||||
<div class="partial-booking--hour">{{ hour|time:"H" }} h</div>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</div>
|
||||
|
||||
</table>
|
||||
<div class="partial-booking--registrant-items">
|
||||
{% for user, bookings in bookings_by_user.items %}
|
||||
<section class="partial-booking--registrant">
|
||||
<h3 class="registrant--name">{{ bookings.0.get_user_block }}</h3>
|
||||
<div class="registrant--datas">
|
||||
{% for booking in bookings %}
|
||||
<div class="registrant--bar-container">
|
||||
<p
|
||||
class="registrant--bar booking"
|
||||
title="{% trans "Booked period" %}"
|
||||
style="left: {{ booking.css_left }}%; width: {{ booking.css_width }}%;"
|
||||
>
|
||||
<strong class="sr-only">{% trans "Booked period:" %}</strong>
|
||||
<time datetime="{{ booking.start_time|time:"H:i" }}">{{ booking.start_time|time:"H:i" }}</time>
|
||||
–
|
||||
<time datetime="{{ booking.end_time|time:"H:i" }}">{{ booking.end_time|time:"H:i" }}</time>
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1509,8 +1509,14 @@ class AgendaDayView(AgendaDateView, DayArchiveView):
|
|||
end_time = datetime.time(min(max_time.hour + 1, 23), 0)
|
||||
context['hours'] = [datetime.time(hour=i) for i in range(start_time.hour, end_time.hour + 1)]
|
||||
|
||||
opening_range_minutes = (
|
||||
(end_time.hour + 1) * 60 + end_time.minute - (start_time.hour * 60 + start_time.minute)
|
||||
)
|
||||
|
||||
def get_time_ratio(t1, t2):
|
||||
return 100 * ((t1.hour - t2.hour) * 60 + t1.minute - t2.minute) // 60
|
||||
return str(
|
||||
round(100 * ((t1.hour - t2.hour) * 60 + t1.minute - t2.minute) / opening_range_minutes, 2)
|
||||
)
|
||||
|
||||
bookings_by_user = collections.defaultdict(list)
|
||||
for booking in event.booking_set.all():
|
||||
|
|
|
@ -104,21 +104,25 @@ def test_manager_partial_bookings_day_view(app, admin_user, freezer):
|
|||
assert 'Month' not in resp.text
|
||||
|
||||
# time range from one hour before event start to one hour after end
|
||||
assert (
|
||||
resp.pyquery('thead th').text()
|
||||
== '7 a.m. 8 a.m. 9 a.m. 10 a.m. 11 a.m. noon 1 p.m. 2 p.m. 3 p.m. 4 p.m. 5 p.m. 6 p.m. 7 p.m.'
|
||||
assert resp.pyquery('.partial-booking--hour')[0].text == '07\u202fh'
|
||||
assert resp.pyquery('.partial-booking--hour')[-1].text == '19\u202fh'
|
||||
assert [int(x.text.replace('\u202fh', '')) for x in resp.pyquery('.partial-booking--hour')] == list(
|
||||
range(7, 20)
|
||||
)
|
||||
|
||||
assert len(resp.pyquery('tbody tr')) == 2
|
||||
assert resp.pyquery('tbody tr th')[0].text == 'Jane Doe'
|
||||
assert resp.pyquery('tbody tr th')[1].text == 'Jon Doe'
|
||||
assert len(resp.pyquery('.partial-booking--registrant')) == 2
|
||||
assert resp.pyquery('.registrant--name')[0].text == 'Jane Doe'
|
||||
assert resp.pyquery('.registrant--name')[1].text == 'Jon Doe'
|
||||
|
||||
assert resp.pyquery('tbody tr div.booking')[0].text == '11 a.m. - 1:30 p.m.'
|
||||
assert resp.pyquery('tbody tr div.booking')[0].attrib['style'] == 'left: 400%; width: 250%;'
|
||||
assert resp.pyquery('tbody tr div.booking')[1].text == '8 a.m. - 10 a.m.'
|
||||
assert resp.pyquery('tbody tr div.booking')[1].attrib['style'] == 'left: 100%; width: 200%;'
|
||||
assert resp.pyquery('tbody tr div.booking')[2].text == 'noon - 2 p.m.'
|
||||
assert resp.pyquery('tbody tr div.booking')[2].attrib['style'] == 'left: 500%; width: 200%;'
|
||||
assert resp.pyquery('.registrant--bar')[0].findall('time')[0].text == '11:00'
|
||||
assert resp.pyquery('.registrant--bar')[0].findall('time')[1].text == '13:30'
|
||||
assert resp.pyquery('.registrant--bar')[0].attrib['style'] == 'left: 30.77%; width: 19.23%;'
|
||||
assert resp.pyquery('.registrant--bar')[1].findall('time')[0].text == '08:00'
|
||||
assert resp.pyquery('.registrant--bar')[1].findall('time')[1].text == '10:00'
|
||||
assert resp.pyquery('.registrant--bar')[1].attrib['style'] == 'left: 7.69%; width: 15.38%;'
|
||||
assert resp.pyquery('.registrant--bar')[2].findall('time')[0].text == '12:00'
|
||||
assert resp.pyquery('.registrant--bar')[2].findall('time')[1].text == '14:00'
|
||||
assert resp.pyquery('.registrant--bar')[2].attrib['style'] == 'left: 38.46%; width: 15.38%;'
|
||||
|
||||
resp = resp.click('Next day')
|
||||
assert 'No opening hours this day.' in resp.text
|
||||
|
@ -135,7 +139,7 @@ def test_manager_partial_bookings_day_view_24_hours(app, admin_user, freezer):
|
|||
today = start_datetime.date()
|
||||
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
|
||||
|
||||
assert resp.pyquery('thead th').text() == (
|
||||
'midnight 1 a.m. 2 a.m. 3 a.m. 4 a.m. 5 a.m. 6 a.m. 7 a.m. 8 a.m. 9 a.m. 10 a.m. 11 a.m. noon '
|
||||
'1 p.m. 2 p.m. 3 p.m. 4 p.m. 5 p.m. 6 p.m. 7 p.m. 8 p.m. 9 p.m. 10 p.m. 11 p.m.'
|
||||
# from 00h to 23h
|
||||
assert [int(x.text.replace('\u202fh', '')) for x in resp.pyquery('.partial-booking--hour')] == list(
|
||||
range(0, 24)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue