Skip to content

Commit

Permalink
Removed delete AJAX requests. Added edit_participation_role/tag permi…
Browse files Browse the repository at this point in the history
…ssions.
  • Loading branch information
dzhuang committed Oct 28, 2020
1 parent 16bd4c3 commit c48e0f1
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 378 deletions.
8 changes: 8 additions & 0 deletions course/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class participation_permission: # noqa
query_participation = "query_participation"
edit_participation = "edit_participation"
preapprove_participation = "preapprove_participation"
edit_participation_role = "edit_participation_role"
edit_participation_tag = "edit_participation_tag"

manage_instant_flow_requests = "manage_instant_flow_requests"

Expand Down Expand Up @@ -249,6 +251,12 @@ class participation_permission: # noqa
pgettext_lazy("Participation permission", "Edit participation")),
(participation_permission.preapprove_participation,
pgettext_lazy("Participation permission", "Preapprove participation")),
(participation_permission.edit_participation_role,
pgettext_lazy(
"Participation permission", "Edit participation role")),
(participation_permission.edit_participation_tag,
pgettext_lazy(
"Participation permission", "Edit participation tag")),

(participation_permission.manage_instant_flow_requests,
pgettext_lazy("Participation permission",
Expand Down
156 changes: 43 additions & 113 deletions course/enrollment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1124,10 +1124,12 @@ def __init__(self, add_new, *args, **kwargs):

if add_new:
self.helper.add_input(
Submit("submit", _("Add")))
Submit("submit", _("Add"), css_class="btn-success"))
else:
self.helper.add_input(
Submit("submit", _("Update")))
Submit("submit", _("Update"), css_class="btn-success"))
self.helper.add_input(
Submit("delete", _("Delete"), css_class="btn-danger"))

class Meta:
model = ParticipationTag
Expand All @@ -1143,18 +1145,13 @@ def view_participation_tag_list(pctx):

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):
if not pctx.has_permission(pperm.edit_participation_tag):
raise PermissionDenied()

request = pctx.request
Expand All @@ -1176,13 +1173,23 @@ def edit_participation_tag(pctx, ptag_id):
form = EditParticipationTagForm(add_new, request.POST, instance=ptag)
try:
if form.is_valid():
# Ref: https://stackoverflow.com/q/21458387/3437454
with transaction.atomic():
form.save()
if add_new:
msg = _("New participation tag saved.")
if "submit" in request.POST or "update" in request.POST:
# Ref: https://stackoverflow.com/q/21458387/3437454
with transaction.atomic():
form.save()

if "submit" in request.POST:
assert add_new
msg = _("New participation tag saved.")
else:
msg = _("Changes saved.")
elif "delete" in request.POST:
ptag.delete()
msg = (_("successfully deleted participation tag '%(tag)s'.")
% {"tag": ptag.name})
else:
msg = _("Changes saved.")
raise SuspiciousOperation(_("invalid operation"))

messages.add_message(request, messages.SUCCESS, msg)
return redirect(
"relate-view_participation_tags", pctx.course.identifier)
Expand All @@ -1199,48 +1206,6 @@ def edit_participation_tag(pctx, ptag_id):
"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"))

# }}}


Expand All @@ -1253,10 +1218,12 @@ def __init__(self, add_new, *args, **kwargs):

if add_new:
self.helper.add_input(
Submit("submit", _("Add")))
Submit("submit", _("Add"), css_class="btn-success"))
else:
self.helper.add_input(
Submit("submit", _("Update")))
Submit("submit", _("Update"), css_class="btn-success"))
self.helper.add_input(
Submit("delete", _("Delete"), css_class="btn-danger"))

class Meta:
model = ParticipationRole
Expand All @@ -1272,18 +1239,13 @@ def view_participation_role_list(pctx):

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):
if not pctx.has_permission(pperm.edit_participation_role):
raise PermissionDenied()

request = pctx.request
Expand All @@ -1305,14 +1267,24 @@ def edit_participation_role(pctx, prole_id):
form = EditParticipationRoleForm(add_new, request.POST, instance=prole)
try:
if form.is_valid():
# Ref: https://stackoverflow.com/q/21458387/3437454
with transaction.atomic():
form.save()

if add_new:
msg = _("New participation role saved.")
if "submit" in request.POST or "update" in request.POST:
# Ref: https://stackoverflow.com/q/21458387/3437454
with transaction.atomic():
form.save()

if "submit" in request.POST:
assert add_new
msg = _("New participation role saved.")
else:
msg = _("Changes saved.")
elif "delete" in request.POST:
prole.delete()
msg = (
_("successfully deleted participation role '%(role)s'.")
% {"role": prole.identifier})
else:
msg = _("Changes saved.")
raise SuspiciousOperation(_("invalid operation"))

messages.add_message(request, messages.SUCCESS, msg)
return redirect(
"relate-view_participation_roles", pctx.course.identifier)
Expand All @@ -1329,48 +1301,6 @@ def edit_participation_role(pctx, prole_id):
"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"))

# }}}


Expand Down
49 changes: 49 additions & 0 deletions course/migrations/0114_added_edit_prole_and_ptag_permission.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Generated by Django 3.0.8 on 2020-10-26 08:48

from __future__ import unicode_literals

from django.db import migrations, models


def add_edit_prole_and_ptag_permission(apps, schema_editor):
from course.constants import participation_permission as pperm

ParticipationRolePermission = apps.get_model("course", "ParticipationRolePermission") # noqa

roles_pks = (
ParticipationRolePermission.objects.filter(
permission=pperm.preapprove_participation)
.values_list("role", flat=True)
)

if roles_pks.count():
for pk in roles_pks:
ParticipationRolePermission.objects.get_or_create(
role_id=pk,
permission=pperm.edit_participation_role
)
ParticipationRolePermission.objects.get_or_create(
role_id=pk,
permission=pperm.edit_participation_tag
)


class Migration(migrations.Migration):

dependencies = [
('course', '0113_merge_20190919_1408'),
]

operations = [
migrations.AlterField(
model_name='participationpermission',
name='permission',
field=models.CharField(choices=[('edit_course', 'Edit course'), ('use_admin_interface', 'Use admin interface'), ('manage_authentication_tokens', 'Manage authentication tokens'), ('impersonate_role', 'Impersonate role'), ('set_fake_time', 'Set fake time'), ('set_pretend_facility', 'Pretend to be in facility'), ('edit_course_permissions', 'Edit course permissions'), ('view_hidden_course_page', 'View hidden course page'), ('view_calendar', 'View calendar'), ('send_instant_message', 'Send instant message'), ('access_files_for', 'Access files for'), ('included_in_grade_statistics', 'Included in grade statistics'), ('skip_during_manual_grading', 'Skip during manual grading'), ('edit_exam', 'Edit exam'), ('issue_exam_ticket', 'Issue exam ticket'), ('batch_issue_exam_ticket', 'Batch issue exam ticket'), ('view_participant_masked_profile', "View participants' masked profile only"), ('view_flow_sessions_from_role', 'View flow sessions from role'), ('view_gradebook', 'View gradebook'), ('edit_grading_opportunity', 'Edit grading opportunity'), ('assign_grade', 'Assign grade'), ('view_grader_stats', 'View grader stats'), ('batch_import_grade', 'Batch-import grades'), ('batch_export_grade', 'Batch-export grades'), ('batch_download_submission', 'Batch-download submissions'), ('impose_flow_session_deadline', 'Impose flow session deadline'), ('batch_impose_flow_session_deadline', 'Batch-impose flow session deadline'), ('end_flow_session', 'End flow session'), ('batch_end_flow_session', 'Batch-end flow sessions'), ('regrade_flow_session', 'Regrade flow session'), ('batch_regrade_flow_session', 'Batch-regrade flow sessions'), ('recalculate_flow_session_grade', 'Recalculate flow session grade'), ('batch_recalculate_flow_session_grade', 'Batch-recalculate flow sesssion grades'), ('reopen_flow_session', 'Reopen flow session'), ('grant_exception', 'Grant exception'), ('view_analytics', 'View analytics'), ('preview_content', 'Preview content'), ('update_content', 'Update content'), ('use_git_endpoint', 'Use direct git endpoint'), ('use_markup_sandbox', 'Use markup sandbox'), ('use_page_sandbox', 'Use page sandbox'), ('test_flow', 'Test flow'), ('edit_events', 'Edit events'), ('query_participation', 'Query participation'), ('edit_participation', 'Edit participation'), ('preapprove_participation', 'Preapprove participation'), ('edit_participation_role', 'Edit participation role'), ('edit_participation_tag', 'Edit participation tag'), ('manage_instant_flow_requests', 'Manage instant flow requests')], db_index=True, max_length=200, verbose_name='Permission'),
),
migrations.AlterField(
model_name='participationrolepermission',
name='permission',
field=models.CharField(choices=[('edit_course', 'Edit course'), ('use_admin_interface', 'Use admin interface'), ('manage_authentication_tokens', 'Manage authentication tokens'), ('impersonate_role', 'Impersonate role'), ('set_fake_time', 'Set fake time'), ('set_pretend_facility', 'Pretend to be in facility'), ('edit_course_permissions', 'Edit course permissions'), ('view_hidden_course_page', 'View hidden course page'), ('view_calendar', 'View calendar'), ('send_instant_message', 'Send instant message'), ('access_files_for', 'Access files for'), ('included_in_grade_statistics', 'Included in grade statistics'), ('skip_during_manual_grading', 'Skip during manual grading'), ('edit_exam', 'Edit exam'), ('issue_exam_ticket', 'Issue exam ticket'), ('batch_issue_exam_ticket', 'Batch issue exam ticket'), ('view_participant_masked_profile', "View participants' masked profile only"), ('view_flow_sessions_from_role', 'View flow sessions from role'), ('view_gradebook', 'View gradebook'), ('edit_grading_opportunity', 'Edit grading opportunity'), ('assign_grade', 'Assign grade'), ('view_grader_stats', 'View grader stats'), ('batch_import_grade', 'Batch-import grades'), ('batch_export_grade', 'Batch-export grades'), ('batch_download_submission', 'Batch-download submissions'), ('impose_flow_session_deadline', 'Impose flow session deadline'), ('batch_impose_flow_session_deadline', 'Batch-impose flow session deadline'), ('end_flow_session', 'End flow session'), ('batch_end_flow_session', 'Batch-end flow sessions'), ('regrade_flow_session', 'Regrade flow session'), ('batch_regrade_flow_session', 'Batch-regrade flow sessions'), ('recalculate_flow_session_grade', 'Recalculate flow session grade'), ('batch_recalculate_flow_session_grade', 'Batch-recalculate flow sesssion grades'), ('reopen_flow_session', 'Reopen flow session'), ('grant_exception', 'Grant exception'), ('view_analytics', 'View analytics'), ('preview_content', 'Preview content'), ('update_content', 'Update content'), ('use_git_endpoint', 'Use direct git endpoint'), ('use_markup_sandbox', 'Use markup sandbox'), ('use_page_sandbox', 'Use page sandbox'), ('test_flow', 'Test flow'), ('edit_events', 'Edit events'), ('query_participation', 'Query participation'), ('edit_participation', 'Edit participation'), ('preapprove_participation', 'Preapprove participation'), ('edit_participation_role', 'Edit participation role'), ('edit_participation_tag', 'Edit participation tag'), ('manage_instant_flow_requests', 'Manage instant flow requests')], db_index=True, max_length=200, verbose_name='Permission'),
),
migrations.RunPython(add_edit_prole_and_ptag_permission),
]
2 changes: 2 additions & 0 deletions course/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@ def add_instructor_permissions(role):
rpm(role=role, permission=pp.edit_events).save()
rpm(role=role, permission=pp.manage_instant_flow_requests).save()
rpm(role=role, permission=pp.preapprove_participation).save()
rpm(role=role, permission=pp.edit_participation_tag).save()
rpm(role=role, permission=pp.edit_participation_role).save()

add_teaching_assistant_permissions(role)

Expand Down
17 changes: 8 additions & 9 deletions course/templates/course/course-base.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@
<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">
{% if pperm.edit_participation or pperm.query_participation %}
<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>
<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>
{% if pperm.query_participation %}
<li><a href="{% url "relate-query_participations" course.identifier %}">{% trans "Query participations" context "menu item" %}</a></li>
{% endif %}
<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 %}
Expand Down Expand Up @@ -144,7 +147,7 @@
</li>
{% endif %}

{% if pperm.query_participation or pperm.manage_instant_flow_requests or pperm.preapprove_participation %}
{% if pperm.manage_instant_flow_requests or pperm.preapprove_participation %}
{% if not pperm.view_participant_masked_profile %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Instructor" context "menu item" %}<b class="caret"></b></a>
Expand All @@ -153,10 +156,6 @@
{% if pperm.preapprove_participation %}
<li><a href="{% url "relate-create_preapprovals" course.identifier %}">{% trans "Preapprove enrollments" context "menu item" %}</a></li>
{% endif %}
{% if pperm.query_participation %}
<li><a href="{% url "relate-query_participations" course.identifier %}">{% trans "Query participations" context "menu item" %}</a></li>
{% endif %}

{% if pperm.manage_instant_flow_requests %}
<li role="presentation" class="divider"></li>
<li role="presentation" class="dropdown-header">{% trans "Instant flow requests" %}</li>
Expand Down
2 changes: 1 addition & 1 deletion course/templates/course/gradebook-participant-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% load static %}

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

{% block header_extra %}
Expand Down
6 changes: 1 addition & 5 deletions course/templates/course/participation-role-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% load static %}

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

{% block header_extra %}
Expand All @@ -19,7 +19,3 @@ <h1>{% trans "Participation roles" %}</h1>
{% 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 c48e0f1

Please sign in to comment.