Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
felixrindt committed Mar 24, 2024
1 parent 00ded5c commit c4830e9
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 119 deletions.
9 changes: 7 additions & 2 deletions ephios/core/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@ def formatday(self, day, weekday):
cssclass += " filled"
content = render_to_string(
"core/fragments/calendar_day.html",
{"day": day, "shifts": self.shifts.get(day, None), "today": today, "date": this_date.isoformat(),
"request": self.request},
{
"day": day,
"shifts": self.shifts.get(day, None),
"today": today,
"date": this_date.isoformat(),
"request": self.request,
},
)
return self.day_cell(cssclass, content)
return self.day_cell("noday", " ")
Expand Down
4 changes: 2 additions & 2 deletions ephios/core/templates/core/fragments/event_list_day_mode.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
<div class="day-calendar-container">
{% for event in event_list %}
<div class="day-calendar-header-{{ event.pk }} day-calendar-head d-flex">
<a class="card mb-0 flex-grow-1 link-underline link-underline-opacity-0 link-underline-opacity-100-hover" href="{{ event.get_absolute_url }}">
<a class="card border-primary m-1 flex-grow-1 link-underline link-underline-opacity-0 link-underline-opacity-100-hover" href="{{ event.get_absolute_url }}">
<div class="card-body pb-0">
<h2 class="card-title fw-bold clearfix fs-6">
<h2 class="card-title text-primary clearfix fs-6">
<span class="overflow-hidden">
{{ event.title }}
</span>
Expand Down
18 changes: 9 additions & 9 deletions ephios/core/templates/core/fragments/event_list_list_mode.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<div class="bulk-actions">
<button class="btn btn-secondary btn-sm m-1 ms-0" type="submit" name="delete"
formaction="{% url "core:event_bulk_delete" %}"><span
class="fa fa-trash-alt"></span> {% translate "Delete selected" %}</button>
class="fa fa-trash-alt"></span> {% translate "Delete selected" %}</button>
{% event_bulk_actions %}
</div>
</div>
Expand All @@ -43,9 +43,9 @@
<li class="list-group-item p-0 d-flex flex-row">
<div class="m-0 py-2 d-flex flex-column flex-lg-row-reverse justify-content-around flex-grow-0">
<div class="ps-lg-2 d-flex flex-row flex-lg-column justify-content-center event-list-status-icon"
{% if counter %}
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true"
title="{% for state in counter %}<div>
{% if counter %}
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-html="true"
title="{% for state in counter %}<div>
Expand All @@ -55,8 +55,8 @@
{% if event.shifts.all|length > 1 %}{{ counter|get:state }} {% endif %}{{ ParticipationStates.labels_dict|get:state }}</div>{% endfor %}"
{% endif %}>
{% if event.shifts.all|length > 1 %}{{ counter|get:state }} {% endif %}{{ ParticipationStates.labels_dict|get:state }}</div>{% endfor %}"
{% endif %}>
{% if counter|get:ParticipationStates.CONFIRMED > 0 %}
<span class="text-success fa fa-user-check ps-2"></span>
{% elif counter|get:ParticipationStates.REQUESTED > 0 %}
Expand Down Expand Up @@ -84,11 +84,11 @@ <h5 class="mb-0 text-break">
{{ event.title }}
</h5>
<span class="w-100 text-body-secondary text-break">
{{ event.location }}
</span>
{{ event.location }}
</span>
</div>
<div class="grid-batch"><span
class="badge eventtype-{{ event.type.pk }}-color">{{ event.type }}</span>
class="badge eventtype-{{ event.type.pk }}-color">{{ event.type }}</span>
</div>
<div class="grid-signup d-flex flex-column align-items-end align-items-lg-center justify-content-center">
<div class="position-relative">
Expand Down
94 changes: 47 additions & 47 deletions ephios/core/templates/core/fragments/shift_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
{% load humanize %}

<div class="card-header d-flex">
{% with mannequin=participation|participation_mannequin_style style=participation|participation_css_style %}
<div class="mannequin mannequin-{{ mannequin }}">
<img src="{% static 'ephios/img/mannequin_'|add:mannequin|add:'.svg' %}"
alt="{{ mannequin }} mannequin icon"/>
</div>
<div class="lh-1 ms-2 flex-grow-1">
{% if not hide_date %}
{% with mannequin=participation|participation_mannequin_style style=participation|participation_css_style %}
<div class="mannequin mannequin-{{ mannequin }}">
<img src="{% static 'ephios/img/mannequin_'|add:mannequin|add:'.svg' %}"
alt="{{ mannequin }} mannequin icon"/>
</div>
<div class="lh-1 ms-2 flex-grow-1">
{% if not hide_date %}
<small class="fw-bold">
{% if participation.start_time|date:"SHORT_DATE_FORMAT" != shift.start_time|date:"SHORT_DATE_FORMAT" and participation.is_in_positive_state %}
<span class="text-{{ style }}" data-bs-toggle="tooltip" data-bs-placement="top"
Expand All @@ -23,45 +23,45 @@
{% endif %}
</small>
<br/>
{% endif %}
<span class="fw-bold fs-2 shift-time">
{% if participation.individual_start_time and participation.is_in_positive_state %}
<span class="text-{{ style }}" data-bs-toggle="tooltip" data-bs-placement="bottom"
title="{% translate "originally" %} {{ shift.start_time|time }}">{{ participation.start_time|time }}</span>
{% else %}
{{ shift.start_time|time }}
{% endif %}
-
{% if participation.individual_end_time and participation.is_in_positive_state %}
<span class="text-{{ style }}" data-bs-toggle="tooltip" data-bs-placement="bottom"
title="{% translate "originally" %} {{ shift.end_time|time }}">{{ participation.end_time|time }}</span>
{% else %}
{{ shift.end_time|time }}
{% endif %}
{% endif %}
<span class="fw-bold fs-2 shift-time">
{% if participation.individual_start_time and participation.is_in_positive_state %}
<span class="text-{{ style }}" data-bs-toggle="tooltip" data-bs-placement="bottom"
title="{% translate "originally" %} {{ shift.start_time|time }}">{{ participation.start_time|time }}</span>
{% else %}
{{ shift.start_time|time }}
{% endif %}
-
{% if participation.individual_end_time and participation.is_in_positive_state %}
<span class="text-{{ style }}" data-bs-toggle="tooltip" data-bs-placement="bottom"
title="{% translate "originally" %} {{ shift.end_time|time }}">{{ participation.end_time|time }}</span>
{% else %}
{{ shift.end_time|time }}
{% endif %}
</span>
<small class="fw-bold text-body-secondary d-inline-block">
<span class="d-inline-block">
{{ shift.meeting_time|time }} {% translate "Meetup" %}
</span>
<small class="fw-bold text-body-secondary d-inline-block">
<span class="d-inline-block">
{{ shift.meeting_time|time }} {% translate "Meetup" %}
</span>
</small>
</div>
{% endwith %}
</small>
</div>
{% endwith %}

{% if "change_event" in event_perms %}
<div class="dropstart">
<button class="btn" type="button" id="actionDropdownButton"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="actionDropdownButton">
<li><a class="dropdown-item" href="{% url "core:shift_edit" shift.pk %}"><span
class="fas fa-edit"></span>
{% translate "Edit" %}</a></li>
{% if shift.event.shifts.count > 1 %}
<a class="dropdown-item" href="{% url "core:shift_delete" shift.pk %}"><span
class="fas fa-trash-alt"></span> {% translate "Delete" %}</a>
{% endif %}
</ul>
</div>
{% endif %}
</div>
{% if "change_event" in event_perms %}
<div class="dropstart">
<button class="btn" type="button" id="actionDropdownButton"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="actionDropdownButton">
<li><a class="dropdown-item" href="{% url "core:shift_edit" shift.pk %}"><span
class="fas fa-edit"></span>
{% translate "Edit" %}</a></li>
{% if shift.event.shifts.count > 1 %}
<a class="dropdown-item" href="{% url "core:shift_delete" shift.pk %}"><span
class="fas fa-trash-alt"></span> {% translate "Delete" %}</a>
{% endif %}
</ul>
</div>
{% endif %}
</div>
89 changes: 42 additions & 47 deletions ephios/core/views/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,67 +349,71 @@ def _get_day_context(self):
ctx.update({"event_list": events, "date": this_date})
return ctx

shifts_by_hour = defaultdict(defaultdict)
css_context = self._build_day_css_context(events, shifts)

shift_starts = {}
shift_ends = {}
ctx.update(
{
"event_list": events,
"date": this_date,
"hours": range(25),
**css_context,
}
)

return ctx

def _build_day_css_context(self, events, shifts):
"""
Build a css grid layout for the day view. Shifts are layouted in columns, with shifts of the same event
being layouted next to each other, needing as few columns as possible.
"""
# pylint: disable=too-many-locals
shifts_by_event_layouted = {}
shortest_shift_duration = timedelta.max
for event in events:
# If two shifts of the same event start within an hour of each other, layout them next to each other
columns = {}
columns = defaultdict(list)
for shift in event.shifts.all():
if shift not in shifts:
continue
duration = shift.end_time - shift.start_time
if duration < shortest_shift_duration:
shortest_shift_duration = duration
shortest_shift_duration = min(shortest_shift_duration, duration)

current_column = 0
# search for first column that fits the shift
while (
current_column in columns
and shift.start_time < columns.get(current_column)[-1].end_time
columns[current_column]
and shift.start_time < columns[current_column][-1].end_time
):
current_column += 1

if current_column in columns:
columns[current_column] += [shift]
else:
columns[current_column] = [shift]

shifts_by_hour[shift.start_time.hour][event.pk] = shift
shift_starts[shift.pk] = shift.start_time
shift_ends[shift.pk] = shift.end_time
columns[current_column].append(shift)

shifts_by_event_layouted[event.pk] = columns

css_shift_tops = ""
earliest_shift_start = min(shift_starts.values())
latest_shift_end = max(shift_ends.values())

earliest_shift_start = min(shift.start_time for shift in shifts)
latest_shift_end = max(shift.end_time for shift in shifts)
# calculate timescale based on shortest shift
# to not make things too small, consider a maximum of 4 hours
shortest_shift_duration_in_hours = min(4, shortest_shift_duration.total_seconds() / 3600)
# seconds per em: the shortest shift should be 3600/300 = 12em high
time_scaling_factor = int(300 * shortest_shift_duration_in_hours)

for pk, start in shift_starts.items():
for shift in shifts:
start_offset = (
start.timestamp() - earliest_shift_start.timestamp()
shift.start_time.timestamp() - earliest_shift_start.timestamp()
) / time_scaling_factor
height = (
shift.end_time.timestamp() - shift.start_time.timestamp()
) / time_scaling_factor
height = (shift_ends[pk].timestamp() - start.timestamp()) / time_scaling_factor
# remove margin from height twice, once for top and once for bottom
height -= 2 * 0.2

css_shift_tops += (
f".day-calendar-shift-{pk} {{ top: {start_offset}em; height: {height}em}}\n"
f".day-calendar-shift-{shift.pk} {{ top: {start_offset}em; height: {height}em}}\n"
)
total_height = (
(latest_shift_end.timestamp() - earliest_shift_start.timestamp()) / time_scaling_factor
) + 2
hour_height = 3600 / time_scaling_factor

css_grid_columns = " "
css_grid_headers = " "
shift_columns = {}
Expand All @@ -421,26 +425,17 @@ def _get_day_context(self):
shift_columns[column_name] = content
max_col = max(max_col, column_idx)
css_grid_headers += f".day-calendar-header-{event.pk} {{ grid-column-start: col-{event.pk}-0; grid-column-end: span {max_col + 1} }}"

ctx.update(
{
"event_list": events,
"date": this_date,
"hours": range(25),
"shifts_by_hour": shifts_by_hour,
"css_grid_columns": css_grid_columns,
"css_grid_headers": css_grid_headers,
"css_shift_tops": css_shift_tops,
"shift_columns": shift_columns,
"columns_by_event": shifts_by_event_layouted,
"total_height": str(total_height),
"hour_height": str(hour_height),
"quarter_hour_height": str(hour_height / 4),
"half_hour_height": str(hour_height / 2),
}
)

return ctx
return {
"css_grid_columns": css_grid_columns,
"css_grid_headers": css_grid_headers,
"css_shift_tops": css_shift_tops,
"hour_height": str(hour_height),
"quarter_hour_height": str(hour_height / 4),
"half_hour_height": str(hour_height / 2),
"shift_columns": shift_columns,
"columns_by_event": shifts_by_event_layouted,
"total_height": str(total_height),
}


class EventDetailView(CustomPermissionRequiredMixin, CanonicalSlugDetailMixin, DetailView):
Expand Down
2 changes: 1 addition & 1 deletion ephios/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ def GET_SITE_URL():
# bootstrap v5 or v6. See https://github.com/twbs/bootstrap/issues/25394 for details on the problem and
# https://security.stackexchange.com/a/167244 on why allowing data: is considered okay
CSP_IMG_SRC = ("'self'", "data:")
CSP_STYLE_SRC = ("'self'")
CSP_STYLE_SRC = "'self'"
CSP_INCLUDE_NONCE_IN = ["style-src"]

# django-crispy-forms
Expand Down
11 changes: 1 addition & 10 deletions ephios/static/ephios/scss/ephios_custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,6 @@ a.badge {
}
}

.day-calendar-container {
display: grid;
}

$shift-box-target: lighten($primary, 20%);
.shift_box:target {
border-color: $shift-box-target;
Expand All @@ -294,6 +290,7 @@ $shift-box-target: lighten($primary, 20%);
// day calendar view

.day-calendar-container {
display: grid;
grid-template-rows: [head] auto [content] 1fr;
height: 100%;
overflow-y: scroll;
Expand All @@ -303,8 +300,6 @@ $shift-box-target: lighten($primary, 20%);

.day-calendar-head {
grid-row: head;
padding-bottom: 0.3em;
background-color: rgba(0, 0, 0, 0.07);
}

.day-calendar-content {
Expand Down Expand Up @@ -333,10 +328,6 @@ $shift-box-target: lighten($primary, 20%);
padding-top: .5em;
}

.day-calendar-content > .card:hover {
z-index: 2;
}

.day-calendar-container .shift-time {
font-size: 1.25rem !important;
}
Expand Down
1 change: 0 additions & 1 deletion tests/core/test_event_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ def test_day_mode_filter(django_app, volunteer, event, conflicting_event):
f'{reverse("core:event_list")}?mode=day&date={event.get_start_time():%Y-%m-%d}',
user=volunteer,
)
response.showbrowser()
filter_form = response.forms["filter-form"]
filter_form["query"] = event.title
response = filter_form.submit()
Expand Down

0 comments on commit c4830e9

Please sign in to comment.