Skip to content

Commit

Permalink
Non-admin CRUD views for ParticipationTag and ParticipationRole
Browse files Browse the repository at this point in the history
  • Loading branch information
dzhuang committed Oct 22, 2020
1 parent 741d027 commit 65744eb
Show file tree
Hide file tree
Showing 10 changed files with 741 additions and 54 deletions.
247 changes: 247 additions & 0 deletions course/enrollment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1114,4 +1114,251 @@ def edit_participation(pctx, participation_id):

# }}}


# {{{ edit_participation_tag

class EditParticipationTagForm(StyledModelForm):
def __init__(self, add_new, *args, **kwargs):
# type: (bool, *Any, **Any) -> None
super(EditParticipationTagForm, self).__init__(*args, **kwargs)

if add_new:
self.helper.add_input(
Submit("submit", _("Add")))
else:
self.helper.add_input(
Submit("submit", _("Update")))

class Meta:
model = ParticipationTag
exclude = ("course",)


@course_view
def view_participation_tag_list(pctx):
if not pctx.has_permission(pperm.view_gradebook):
raise PermissionDenied(_("may not edit participation tags"))

participation_tags = list(ParticipationTag.objects.filter(course=pctx.course))

return render_course_page(pctx, "course/participation-tag-list.html", {
"participation_tags": participation_tags,

# Wrappers used by JavaScript template (tmpl) so as not to
# conflict with Django template's tag wrapper
"JQ_OPEN": "{%",
"JQ_CLOSE": "%}",
})


@course_view
def edit_participation_tag(pctx, ptag_id):
# type: (CoursePageContext, int) -> http.HttpResponse
if not pctx.has_permission(pperm.edit_participation):
raise PermissionDenied()

request = pctx.request

num_ptag_id = int(ptag_id)

if num_ptag_id == -1:
ptag = ParticipationTag(course=pctx.course)
add_new = True
else:
ptag = get_object_or_404(ParticipationTag, id=num_ptag_id)
add_new = False

if ptag.course.id != pctx.course.id:
raise SuspiciousOperation(
"may not edit participation tag in different course")

if request.method == "POST":
form = EditParticipationTagForm(add_new, request.POST, instance=ptag)
try:
if form.is_valid():
form.save()
messages.add_message(request, messages.SUCCESS, _("Changes saved."))
return redirect(
"relate-view_participation_tags", pctx.course.identifier)
except IntegrityError:
messages.add_message(
request, messages.ERROR,
_("A participation tag with that name already exists."))

else:
form = EditParticipationTagForm(add_new, instance=ptag)

return render_course_page(pctx, "course/generic-course-form.html", {
"form_description": _("Edit Participation Tag"),
"form": form,
})


@course_view
def delete_participation_tag(pctx, ptag_id):
# type: (CoursePageContext, int) -> http.HttpResponse

if not pctx.has_permission(pperm.edit_participation):
raise PermissionDenied()

request = pctx.request

if not request.is_ajax() or request.method != "POST":
raise PermissionDenied(_("only AJAX POST is allowed"))

num_ptag_id = int(ptag_id)

ptag = get_object_or_404(ParticipationTag, id=num_ptag_id)

if ptag.course.id != pctx.course.id:
raise SuspiciousOperation(
"may not delete participation tag in different course")

if "delete" in request.POST:
try:
ptag.delete()
except Exception as e:
return http.JsonResponse(
{"error": _(
"Error when deleting participation tag '%(tag)s'."
" %(error_type)s: %(error)s.") % {
"tag": ptag.name,
"error_type": type(e).__name__,
"error": str(e)}},
status=400)
else:
return http.JsonResponse(
{"message": _("successfully deleted participation tag '%(tag)s'.")
% {"tag": ptag.name},
"message_level": messages.DEFAULT_TAGS[messages.SUCCESS]})

else:
raise SuspiciousOperation(_("invalid operation"))

# }}}


# {{{ edit_participation_role

class EditParticipationRoleForm(StyledModelForm):
def __init__(self, add_new, *args, **kwargs):
# type: (bool, *Any, **Any) -> None
super(EditParticipationRoleForm, self).__init__(*args, **kwargs)

if add_new:
self.helper.add_input(
Submit("submit", _("Add")))
else:
self.helper.add_input(
Submit("submit", _("Update")))

class Meta:
model = ParticipationRole
exclude = ("course",)


@course_view
def view_participation_role_list(pctx):
if not pctx.has_permission(pperm.view_gradebook):
raise PermissionDenied(_("may not edit participation tags"))

participation_roles = list(ParticipationRole.objects.filter(course=pctx.course))

return render_course_page(pctx, "course/participation-role-list.html", {
"participation_roles": participation_roles,

# Wrappers used by JavaScript template (tmpl) so as not to
# conflict with Django template's tag wrapper
"JQ_OPEN": "{%",
"JQ_CLOSE": "%}",
})


@course_view
def edit_participation_role(pctx, prole_id):
# type: (CoursePageContext, int) -> http.HttpResponse
if not pctx.has_permission(pperm.edit_participation):
raise PermissionDenied()

request = pctx.request

num_prole_id = int(prole_id)

if num_prole_id == -1:
prole = ParticipationRole(course=pctx.course)
add_new = True
else:
prole = get_object_or_404(ParticipationRole, id=num_prole_id)
add_new = False

if prole.course.id != pctx.course.id:
raise SuspiciousOperation(
"may not edit participation role in different course")

if request.method == "POST":
form = EditParticipationRoleForm(add_new, request.POST, instance=prole)
try:
if form.is_valid():
form.save()
messages.add_message(request, messages.SUCCESS, _("Changes saved."))
return redirect(
"relate-view_participation_roles", pctx.course.identifier)
except IntegrityError:
messages.add_message(
request, messages.ERROR,
_("A participation role with that name already exists."))

else:
form = EditParticipationRoleForm(add_new, instance=prole)

return render_course_page(pctx, "course/generic-course-form.html", {
"form_description": _("Edit Participation Role"),
"form": form,
})


@course_view
def delete_participation_role(pctx, prole_id):
# type: (CoursePageContext, int) -> http.HttpResponse

if not pctx.has_permission(pperm.edit_participation):
raise PermissionDenied()

request = pctx.request

if not request.is_ajax() or request.method != "POST":
raise PermissionDenied(_("only AJAX POST is allowed"))

num_prole_id = int(prole_id)

prole = get_object_or_404(ParticipationRole, id=num_prole_id)

if prole.course.id != pctx.course.id:
raise SuspiciousOperation(
"may not delete participation role in different course")

if "delete" in request.POST:
try:
prole.delete()
except Exception as e:
return http.JsonResponse(
{"error": _(
"Error when deleting participation role '%(role)s'."
" %(error_type)s: %(error)s.") % {
"role": prole.identifier,
"error_type": type(e).__name__,
"error": str(e)}},
status=400)
else:
return http.JsonResponse(
{"message": _("successfully deleted participation role '%(role)s'.")
% {"role": prole.identifier},
"message_level": messages.DEFAULT_TAGS[messages.SUCCESS]})

else:
raise SuspiciousOperation(_("invalid operation"))

# }}}


# vim: foldmethod=marker
11 changes: 8 additions & 3 deletions course/templates/course/course-base.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,23 @@
</li>
{% endif %}

{% if pperm.view_gradebook %}
{% if pperm.view_gradebook or pperm.edit_participation %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Grading" context "menu item" %}<b class="caret"></b></a>
<ul class="dropdown-menu">
<li role="presentation" class="dropdown-header">{% trans "Participations" %}</li>
<li><a href="{% url "relate-view_participant_list" course.identifier %}">{% trans "List of participants" %}</a></li>
{% if pperm.edit_participation %}
<li><a href="{% url "relate-view_participation_roles" course.identifier %}">{% trans "Participation roles" %}</a></li>
<li><a href="{% url "relate-view_participation_tags" course.identifier %}">{% trans "Participation tags" %}</a></li>
<li role="presentation" class="divider"></li>
{% endif %}
{% if pperm.view_analytics %}
<li><a href="{% url "relate-flow_list" course.identifier %}">{% trans "Analytics Overview" %}</a></li>
{% endif %}

{% if pperm.view_gradebook %}
<li role="presentation" class="divider"></li>
<li role="presentation" class="dropdown-header">{% trans "Grade Book" %}</li>
<li><a href="{% url "relate-view_participant_list" course.identifier %}">{% trans "List of Participants" %}</a></li>
<li><a href="{% url "relate-view_grading_opportunity_list" course.identifier %}">{% trans "List of Grading Opportunities" %}</a></li>
<li><a href="{% url "relate-view_gradebook" course.identifier %}">{% trans "Grade book" %}</a></li>
{% if pperm.batch_export_grade %}
Expand Down
4 changes: 2 additions & 2 deletions course/templates/course/gradebook-participant-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
{% load static %}

{% block title %}
{% trans "List of Participants" %} - {{ relate_site_name }}
{% trans "List of participants" %} - {{ relate_site_name }}
{% endblock %}

{% block header_extra %}
{% include "datatables-header.html" %}
{% endblock %}

{% block content %}
<h1>{% trans "List of Participants" %}</h1>
<h1>{% trans "List of participants" %}</h1>

<a href="{% url "relate-edit_participation" course.identifier -1 %}" class="btn btn-default">{% trans "Add participant" %}</a>

Expand Down
25 changes: 25 additions & 0 deletions course/templates/course/participation-role-list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "course/course-base.html" %}
{% load i18n %}

{% load static %}

{% block title %}
{% trans "Participation roles" %} - {{ relate_site_name }}
{% endblock %}

{% block header_extra %}
{% include "datatables-header.html" %}
{% endblock %}

{% block content %}
<h1>{% trans "Participation roles" %}</h1>

<a href="{% url "relate-edit_participation_role" course.identifier -1 %}" class="btn btn-default">{% trans "Add participation role" %}</a>

{% include "course/participation-role-table.html" with participation_roles=participation_roles %}

{% endblock %}

{% block page_bottom_javascript_extra %}
<script src="{{ STATIC_URL }}blueimp-tmpl/js/tmpl.min.js"></script>
{% endblock %}
Loading

0 comments on commit 65744eb

Please sign in to comment.