Skip to content

Commit 1ff65f7

Browse files
feat(enrichment): implement making multiple enrichments
1 parent caa7e60 commit 1ff65f7

11 files changed

Lines changed: 213 additions & 2 deletions

File tree

intranet/apps/enrichment/forms.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import datetime # for mass form
2+
13
from django import forms
24

35
from .models import EnrichmentActivity
@@ -13,3 +15,61 @@ class Meta:
1315
model = EnrichmentActivity
1416

1517
fields = ["title", "description", "time", "location", "capacity", "presign", "groups_allowed", "groups_blacklisted"]
18+
19+
20+
WEEKDAY_FIELDS = [
21+
("monday", "Monday"),
22+
("tuesday", "Tuesday"),
23+
("wednesday", "Wednesday"),
24+
("thursday", "Thursday"),
25+
("friday", "Friday"),
26+
]
27+
28+
29+
class EnrichmentActivityBulkForm(EnrichmentActivityForm):
30+
31+
"""A way to create multiple enrichment activities at once.
32+
33+
A user would check off boxes given a date in the selected week.
34+
"""
35+
36+
week_of = forms.DateField(
37+
label="Target Week",
38+
widget=forms.DateInput(attrs={"type": "date"}),
39+
)
40+
monday = forms.BooleanField(label="Monday", required=False)
41+
tuesday = forms.BooleanField(label="Tuesday", required=False)
42+
wednesday = forms.BooleanField(label="Wednesday", required=False)
43+
thursday = forms.BooleanField(label="Thursday", required=False)
44+
friday = forms.BooleanField(label="Friday", required=False)
45+
activity_time = forms.TimeField(label="Time of day", widget=forms.TimeInput(attrs={"type": "time"}), initial=datetime.time(12, 0))
46+
47+
def __init__(self, *args, **kwargs):
48+
super().__init__(*args, **kwargs)
49+
# remove time so it doesn't appear in the form
50+
self.fields.pop("time")
51+
52+
def clean(self):
53+
cleaned = super().clean()
54+
# Require at least one day to be checked
55+
days_checked = any(cleaned.get(day) for day, _ in WEEKDAY_FIELDS)
56+
if not days_checked:
57+
raise forms.ValidationError("Please select at least one day of the week.")
58+
return cleaned
59+
60+
def get_selected_dates(self): # returns in the form of a list.
61+
week_of = self.cleaned_data["week_of"]
62+
activity_time = self.cleaned_data["activity_time"]
63+
monday = week_of - datetime.timedelta(days=week_of.weekday())
64+
offsets = {
65+
"monday": 0,
66+
"tuesday": 1,
67+
"wednesday": 2,
68+
"thursday": 3,
69+
"friday": 4,
70+
}
71+
return [
72+
datetime.datetime.combine(monday + datetime.timedelta(days=offset), activity_time)
73+
for day_name, offset in offsets.items()
74+
if self.cleaned_data.get(day_name)
75+
]

intranet/apps/enrichment/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
urlpatterns = [
1010
path("", views.enrichment_view, name="enrichment"),
1111
path("/add", views.add_enrichment_view, name="add_enrichment"),
12+
path("/bulk_create", views.enrichment_bulk_create_view, name="enrichment_bulk_create"),
1213
path("/modify/<int:enrichment_id>", views.modify_enrichment_view, name="modify_enrichment"),
1314
path("/delete/<int:enrichment_id>", views.delete_enrichment_view, name="delete_enrichment"),
1415
path("/join/<int:enrichment_id>", views.enrichment_signup_view, name="enrichment_signup"),

intranet/apps/enrichment/views.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from ...utils.html import safe_html
1212
from ..auth.decorators import deny_restricted
13-
from .forms import EnrichmentActivityForm
13+
from .forms import EnrichmentActivityBulkForm, EnrichmentActivityForm
1414
from .models import EnrichmentActivity
1515

1616
logger = logging.getLogger(__name__)
@@ -309,13 +309,57 @@ def add_enrichment_view(request):
309309
return render(request, "enrichment/add_modify.html", context)
310310

311311

312+
@login_required
313+
@deny_restricted
314+
def enrichment_bulk_create_view(request):
315+
"""
316+
View for creating multiple enrichments.
317+
318+
Get requests will render bulk-create form with Mon-Fri checkboxes.
319+
Post requests create one EnrichmentActivity for each checked day and then redirect.
320+
"""
321+
is_enrichment_admin = request.user.has_admin_permission("enrichment")
322+
if not is_enrichment_admin:
323+
raise http.Http404
324+
325+
if request.method == "POST":
326+
form = EnrichmentActivityBulkForm(data=request.POST)
327+
if form.is_valid():
328+
created = []
329+
for dt in form.get_selected_dates():
330+
activity = form.save(commit=False)
331+
activity.pk = None
332+
activity.time = dt
333+
activity.save()
334+
form.save_m2m()
335+
created.append(dt.strftime("%A, %b %-d"))
336+
337+
messages.success(
338+
request,
339+
f"Created {len(created)} enrichment activities: " + ", ".join(created),
340+
)
341+
return redirect("enrichment")
342+
else:
343+
form = EnrichmentActivityBulkForm()
344+
345+
return render(
346+
request,
347+
"enrichment/bulk_create.html",
348+
{"form": form},
349+
)
350+
351+
312352
@login_required
313353
@deny_restricted
314354
def modify_enrichment_view(request, enrichment_id):
315355
"""Modify enrichment activity page.
316356
317357
Args:
318-
enrichment_id (int): enrichment activity id
358+
request (HttpRequest): The HTTP request object.
359+
enrichment_id (int): The unique identifier of the enrichment activity.
360+
361+
Returns:
362+
HttpResponse: The rendered page or a redirect response.
319363
"""
320364

321365
enrichment = get_object_or_404(EnrichmentActivity, id=enrichment_id)

intranet/static/js/common.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/* Common JS */
2+
<<<<<<< HEAD
23
/* global $, Cookies */
4+
=======
5+
/* global $ */
6+
>>>>>>> 5b991f720 (refactor: update to jquery 3.7.1)
37

48
function csrfSafeMethod(method) {
59
// these HTTP methods do not require CSRF protection
@@ -47,7 +51,11 @@ $(function() {
4751
$("table[data-sortable] thead th[data-auto-sort]").trigger("click");
4852

4953

54+
<<<<<<< HEAD
5055
let collapseWarning = Cookies.get("collapseWarning") === "true";
56+
=======
57+
let collapseWarning = $.cookie("collapseWarning") === "true";
58+
>>>>>>> 5b991f720 (refactor: update to jquery 3.7.1)
5159
$(".warning-title").on("click", function() {
5260
$(".warning-content").slideToggle();
5361
$(".warning-toggle-icon").toggleClass("fa-chevron-down fa-chevron-up");
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{% extends "page_with_nav.html" %}
2+
{% load static %}
3+
{% load dates %}
4+
{% load pipeline %}
5+
{% block title %}
6+
{{ block.super }} - Bulk Create Enrichment Activities
7+
{% endblock %}
8+
{% block js %}
9+
{{ block.super }}
10+
<script src="{% static 'vendor/selectize.js-0.12.4/dist/js/standalone/selectize.min.js' %}"></script>
11+
<script>
12+
$(function() {
13+
$("#id_groups_allowed").selectize({
14+
create: false
15+
})
16+
$("#id_groups_blacklisted").selectize({
17+
create: false
18+
});
19+
});
20+
</script>
21+
{% endblock %}
22+
{% block css %}
23+
{{ block.super }}
24+
<link rel="stylesheet" href="{% static 'vendor/selectize.js-0.12.4/dist/css/selectize.default.css' %}">
25+
{% stylesheet 'announcements.form' %}
26+
{% stylesheet 'enrichment' %}
27+
{% endblock %}
28+
{% block head %}
29+
{% if dark_mode_enabled %}
30+
{% stylesheet 'dark/base' %}
31+
{% stylesheet 'dark/nav' %}
32+
{% stylesheet 'dark/events' %}
33+
{% endif %}
34+
{% endblock %}
35+
{% block main %}
36+
<div class="events enrichment announcements primary-content">
37+
<h2>Bulk Create Enrichment Activities</h2>
38+
<p>Choose a week for your activity, and check off the days you want. One activity will be created for each checked day.</p>
39+
<form method="post" id="event_form">
40+
<table>
41+
{% csrf_token %}
42+
<tr><th><label for="id_title">Title:</label></th><td>{{ form.title }}{{ form.title.errors }}</td></tr>
43+
<tr><th><label for="id_description">Description:</label></th><td>{{ form.description }}{{ form.description.errors }}</td></tr>
44+
<tr><th><label for="id_capacity">Capacity:</label></th><td>{{ form.capacity }}{{ form.capacity.errors }}</td></tr>
45+
<tr><th><label for="id_location">Location:</label></th><td>{{ form.location }}{{ form.location.errors }}</td></tr>
46+
<tr><th><label for="id_groups_allowed">Groups allowed:</label></th><td>{{ form.groups_allowed }}{{ form.groups_allowed.errors }}</td></tr>
47+
<tr><th><label for="id_groups_blacklisted">Groups blacklisted:</label></th><td>{{ form.groups_blacklisted }}{{ form.groups_blacklisted.errors }}</td></tr>
48+
<tr><th><label for="id_presign">Presign:</label></th><td>{{ form.presign }}{{ form.presign.errors }}</td></tr>
49+
<tr><th><label for="id_week_of">Week of:</label></th><td>{{ form.week_of }}{{ form.week_of.errors }}</td></tr>
50+
<tr><th><label for="id_activity_time">Time of day:</label></th><td>{{ form.activity_time }}{{ form.activity_time.errors }}</td></tr>
51+
<tr>
52+
<td><b>Days of the week:</b></td>
53+
<td>
54+
<div class="weekday-checkboxes">
55+
{# creates a day checkbox within the weekday checkboxes for each day #}
56+
<label class="day-checkbox">{{ form.monday }} {{ form.monday.label }}</label>
57+
<label class="day-checkbox">{{ form.tuesday }} {{ form.tuesday.label }}</label>
58+
<label class="day-checkbox">{{ form.wednesday }} {{ form.wednesday.label }}</label>
59+
<label class="day-checkbox">{{ form.thursday }} {{ form.thursday.label }}</label>
60+
<label class="day-checkbox">{{ form.friday }} {{ form.friday.label }}</label>
61+
</div>
62+
{% if form.non_field_errors %}
63+
<ul class="errorlist">{{ form.non_field_errors }}</ul>
64+
{% endif %}
65+
</td>
66+
</tr>
67+
<tr><td>&nbsp;</td><td>
68+
<input type="submit" style="width: 270px" value="Bulk Create Enrichment">
69+
<a href="{% url 'enrichment' %}" class="button">Cancel</a>
70+
</td></tr>
71+
</table>
72+
</form>
73+
</div>
74+
{% endblock %}

intranet/templates/enrichment/home.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ <h2>Enrichment</h2>
101101
<i class="fas fa-plus"></i>
102102
Add
103103
</a>
104+
<a href="{% url 'enrichment_bulk_create' %}" class="button"> <i class="fas fa-plus"></i> Bulk Create (by week) </a>
104105
{% endif %}
105106

106107
</div>

intranet/templates/oauth2_provider/base.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
{% stylesheet 'oauth' %}
2020
{% endblock %}
2121
{% block js %}
22+
<<<<<<< HEAD
2223
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
2324
<script src="https://code.jquery.com/jquery-migrate-4.0.2.min.js"></script>
25+
=======
26+
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
27+
>>>>>>> 5b991f720 (refactor: update to jquery 3.7.1)
2428
{% endblock %}
2529
{% if dark_mode_enabled %}
2630
{% stylesheet 'dark/base' %}

intranet/templates/page_base.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,14 @@
3636
{% endif %}
3737

3838
{% block js %}
39+
<<<<<<< HEAD
3940
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
4041
<script src="https://code.jquery.com/jquery-migrate-4.0.2.min.js"></script>
4142
<script src="{% static 'js/vendor/js.cookie.min.js' %}"></script>
43+
=======
44+
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
45+
<script src="{% static 'js/vendor/jquery.cookie.js' %}"></script>
46+
>>>>>>> 5b991f720 (refactor: update to jquery 3.7.1)
4247
<script src="{% static 'js/vendor/modernizr.js' %}"></script>
4348
<script src="{% static 'js/common.js' %}"></script>
4449

intranet/templates/schedule/embed.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,14 @@
3232
</style>
3333

3434

35+
<<<<<<< HEAD
3536
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
3637
<script src="https://code.jquery.com/jquery-migrate-4.0.2.min.js"></script>
3738
<script src="{% static 'js/vendor/js.cookie.min.js' %}"></script>
39+
=======
40+
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
41+
<script src="{% static 'js/vendor/jquery.cookie.js' %}"></script>
42+
>>>>>>> 5b991f720 (refactor: update to jquery 3.7.1)
3843
<script src="{% static 'js/common.js' %}"></script>
3944
<script src="{% static 'js/schedule.js' %}"></script>
4045
<script src="{% static 'js/login.js' %}"></script>

intranet/templates/schedule/week_view.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@
2323
</style>
2424

2525

26+
<<<<<<< HEAD
2627
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
2728
<script src="https://code.jquery.com/jquery-migrate-4.0.2.min.js"></script>
2829
<script src="{% static 'js/vendor/js.cookie.min.js' %}"></script>
30+
=======
31+
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
32+
<script src="{% static 'js/vendor/jquery.cookie.js' %}"></script>
33+
>>>>>>> 5b991f720 (refactor: update to jquery 3.7.1)
2934
<script src="{% static 'js/common.js' %}"></script>
3035
<script src="{% static 'js/schedule.js' %}"></script>
3136
<script src="{% static 'js/login.js' %}"></script>

0 commit comments

Comments
 (0)