Skip to content

Commit

Permalink
Add submission tags
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelGusse committed Apr 24, 2024
1 parent ce46d6f commit d43a3b0
Show file tree
Hide file tree
Showing 17 changed files with 406 additions and 6 deletions.
32 changes: 31 additions & 1 deletion course/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
from exercise.exercise_models import LearningObject
from threshold.models import CourseModuleRequirement


logger = logging.getLogger('aplus.course')

# Read pseudonymization data from file
Expand Down Expand Up @@ -347,6 +346,37 @@ def is_valid_slug(self, slug_candidate): # pylint: disable=arguments-renamed
return not qs.exists()


class SubmissionTag(UrlMixin, ColorTag):
course_instance = models.ForeignKey('CourseInstance',
verbose_name=_('LABEL_COURSE_INSTANCE'),
on_delete=models.CASCADE,
related_name="submissiontags",
)

visible_to_students = models.BooleanField(
verbose_name=_('LABEL_VISIBLE_TO_STUDENTS'),
default=False,
)

class Meta:
verbose_name = _('MODEL_NAME_SUBMISSION_TAG')
verbose_name_plural = _('MODEL_NAME_SUBMISSION_TAG_PLURAL')
ordering = ['course_instance', 'name']

def get_url_kwargs(self):
return dict(tag_id=self.id, **self.course_instance.get_url_kwargs()) # pylint: disable=use-dict-literal

def is_valid_slug(self, slug_candidate): # pylint: disable=arguments-renamed
assert self.course_instance
if not slug_candidate:
return False
qs = self.__class__.objects.filter(
course_instance=self.course_instance, slug=slug_candidate)
if self.pk is not None:
qs = qs.exclude(pk=self.pk)
return not qs.exists()


class HardcodedUserTag(UserTag):
class Meta:
verbose_name = _('MODEL_NAME_HARDCODED_USER_TAG')
Expand Down
47 changes: 46 additions & 1 deletion edit_course/course_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
from django_colortag.forms import ColorTagForm

from aplus.api import api_reverse
from course.models import LearningObjectCategory, CourseModule, CourseInstance, UserTag
from course.models import LearningObjectCategory, CourseModule, CourseInstance, UserTag, SubmissionTag
from course.sis import get_sis_configuration, StudentInfoSystem
from exercise.models import CourseChapter
from exercise.submission_models import SubmissionTagging
from lib.validators import generate_url_key_validator
from lib.fields import UsersSearchSelectField
from lib.widgets import DateTimeLocalInput
Expand Down Expand Up @@ -267,6 +268,13 @@ class CloneInstanceForm(forms.Form):
required=False,
initial=True,
)
submissiontags = forms.BooleanField(
label=_('LABEL_SUBMISSION_TAGS'),
help_text=_('LABEL_SUBMISSION_TAGS_HELPTEXT'),
required=False,
initial=True,
)

if settings.GITMANAGER_URL:
key_year = forms.IntegerField(
label=_('LABEL_YEAR'),
Expand Down Expand Up @@ -400,6 +408,30 @@ def get_base_object(self, course_instance):
return obj


class SubmissionTagForm(ColorTagForm):

class Meta(ColorTagForm.Meta):
model = SubmissionTag
fields = [
'name',
'slug',
'description',
'color',
]
labels = {
'name': _('LABEL_NAME'),
'slug': _('LABEL_SLUG'),
'description': _('LABEL_DESCRIPTION'),
'color': _('LABEL_COLOR'),
}

@classmethod
def get_base_object(self, course_instance):
obj = self.Meta.model()
obj.course_instance = course_instance
return obj


class SelectUsersForm(forms.Form):
user = UsersSearchSelectField(queryset=UserProfile.objects.none(),
initial_queryset=UserProfile.objects.none())
Expand All @@ -412,6 +444,19 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
self.fields['user'].queryset = course_instance.get_student_profiles()


class SubmissionTaggingForm(forms.ModelForm):
class Meta(ColorTagForm.Meta):
model = SubmissionTagging
fields = [
'tag',
'submission',
]
labels = {
'tag': _('LABEL_SUBMISSION_TAG'),
'submission': _('LABEL_SUBMISSION'),
}


class GitmanagerForm(forms.Form):
key = forms.SlugField(
label=_('LABEL_KEY'),
Expand Down
5 changes: 5 additions & 0 deletions edit_course/templates/edit_course/edit_course_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
<a href="{{ instance|url:'course-tags' }}">
{% translate "TAGS" %}
</a>
</li>
<li role="presentation" class="menu-course-submission-tags">
<a href="{{ instance|url:'course-submission-tags' }}">
{% translate "SUBMISSION_TAGS" %}
</a>
</li>
<li role="presentation" class="menu-batch-assess">
<a href="{{ instance|url:'batch-assess' }}">
Expand Down
27 changes: 27 additions & 0 deletions edit_course/templates/edit_course/submissiontag_add.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "edit_course/edit_course_base.html" %}
{% load i18n %}
{% load bootstrap %}
{% load course %}
{% load editcourse %}

{% block editbreadcrumblist %}
{{ block.super }}
<li><a href="{{ instance|url:'course-submission-tags' }}">{% translate "SUBMISSION_TAGS" %}</a></li>
<li class="active">{% translate "ADD_NEW_SUBMISSION_TAG" %}</li>
{% endblock %}
{% block view_tag %}edit-course,course-submission-tags{% endblock %}

{% block coursecontent %}
<br />
<form method="post" class="well form-horizontal">
{% csrf_token %}
<legend>{% translate "ADD_SUBMISSION_TAG" %}</legend>
{{ form|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<button type="submit" class="aplus-button--default aplus-button--md">{% translate "SAVE" %}</button>
<a href="{{ instance|url:'course-submission-tags' }}" class="aplus-button--secondary aplus-button--md" role="button">{% translate "CANCEL" %}</a>
</div>
</div>
</form>
{% endblock %}
36 changes: 36 additions & 0 deletions edit_course/templates/edit_course/submissiontag_delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% extends "edit_course/edit_course_base.html" %}
{% load i18n %}
{% load bootstrap %}
{% load course %}
{% load editcourse %}
{% load colortag %}

{% block editbreadcrumblist %}
{{ block.super }}
<li><a href="{{ instance|url:'course-tags' }}">{% translate "TAGS" %}</a></li>
<li class="active">{% translate "REMOVE_SUBMISSION_TAG" %}</li>
{% endblock %}
{% block view_tag %}edit-course,course-submission-tags{% endblock %}

{% block coursecontent %}
<br />
<form method="post" class="well form-horizontal">
{% csrf_token %}
<legend>
{% translate "REMOVE_SUBMISSION_TAG_CONFIRMATION" %}
</legend>

<div class="alert alert-danger">
{% translate "REMOVE_SUBMISSION_TAG_CONFIRMATION_ALERT" %}
{{ object|colortag }}
</div>

<div class="form-group">
<input class="aplus-button--danger aplus-button--md" type="submit" value="{% translate 'REMOVE' %}" />
<a class="aplus-button--secondary aplus-button--md" role="button" href="{{ instance|url:'course-submission-tags' }}">
{% translate "CANCEL" %}
</a>
</div>
</form>

{% endblock %}
27 changes: 27 additions & 0 deletions edit_course/templates/edit_course/submissiontag_edit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "edit_course/edit_course_base.html" %}
{% load i18n %}
{% load bootstrap %}
{% load course %}
{% load editcourse %}

{% block editbreadcrumblist %}
{{ block.super }}
<li><a href="{{ instance|url:'course-submission-tags' }}">{% translate "SUBMISSION_TAGS" %}</a></li>
<li class="active">{% translate "EDIT_SUBMISSION_TAG" %}</li>
{% endblock %}
{% block view_tag %}edit-course,course-submission-tags{% endblock %}

{% block coursecontent %}
<br />
<form method="post" class="well form-horizontal">
{% csrf_token %}
<legend>{% translate "EDIT_SUBMISSION_TAG" %}</legend>
{{ form|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<button type="submit" class="aplus-button--default aplus-button--md">{% translate "SAVE" %}</button>
<a href="{{ instance|url:'course-submission-tags' }}" role="button" class="aplus-button--secondary aplus-button--md">{% translate "CANCEL" %}</a>
</div>
</div>
</form>
{% endblock %}
58 changes: 58 additions & 0 deletions edit_course/templates/edit_course/submissiontag_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{% extends "edit_course/edit_course_base.html" %}
{% load i18n %}
{% load bootstrap %}
{% load course %}
{% load editcourse %}
{% load colortag %}

{% block editbreadcrumblist %}
{{ block.super }}
<li class="active">{% translate "TAGS" %}</li>
{% endblock %}
{% block view_tag %}edit-course,course-submission-tags{% endblock %}

{% block coursecontent %}
<br />
<p>
<a class="aplus-button--secondary aplus-button--sm" role="button" href="{{ instance|url:'course-submission-tags-add' }}">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
{% translate "ADD_NEW_SUBMISSION_TAG" %}
</a>
</p>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{% translate "SUBMISSION_TAGS" %}</h3>
</div>
<table class="table table-striped table-bordered table-condensed">
<tr>
<th>{% translate "TAG" %}</th>
<th>{% translate "SLUG" %}</th>
<th>{% translate "DESCRIPTION" %}</th>
<th>{% translate "ACTIONS" %}</th>
</tr>
{% with hide_tooltip=True %}
{% for tag in object_list %}
<tr>
<td>{{ tag|colortag }}</td>
<td>{{ tag.slug }}</td>
<td>{{ tag.description }}</td>
<td>
<a href="{{ tag|url:'course-submission-tags-edit' }}" class="aplus-button--secondary aplus-button--xs" role="button">
<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
{% translate "EDIT" %}
</a>
<a href="{{ tag|url:'course-submission-tags-remove' }}" class="aplus-button--secondary aplus-button--xs" role="button">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
{% translate "REMOVE" %}
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4">{% translate "NO_SUBMISSION_TAGS" %}</td>
</tr>
{% endfor %}
{% endwith %}
</table>
</div>
{% endblock %}
28 changes: 28 additions & 0 deletions edit_course/templates/edit_course/submissiontagging_add.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% extends "edit_course/edit_course_base.html" %}
{% load i18n %}
{% load bootstrap %}
{% load course %}
{% load editcourse %}
{% load static %}

{% block editbreadcrumblist %}
{{ block.super }}
<li><a href="{{ instance|url:'course-submission-tags' }}">{% translate "TAGS" %}</a></li>
<li class="active">{% translate "ADD_NEW_SUBMISSION_TAGGING" %}</li>
{% endblock %}
{% block view_tag %}edit-course,course-submission-tags{% endblock %}

{% block coursecontent %}
<br />
<form method="post" class="well form-horizontal">
{% csrf_token %}
<legend>{% translate "ADD_NEW_SUBMISSION_TAGGING" %}</legend>
{{ form|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<button type="submit" class="aplus-button--default aplus-button--md">{% translate "SAVE" %}</button>
<a href="{{ instance|url:'course-submission-tags' }}" role="button" class="aplus-button--secondary aplus-button--md">{% translate "CANCEL" %}</a>
</div>
</div>
</form>
{% endblock %}
12 changes: 12 additions & 0 deletions edit_course/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
re_path(EDIT_URL_PREFIX + r'tags/(?P<tag_id>\d+)/new-tagging$',
views.UserTaggingAddView.as_view(),
name='course-taggings-add'),
re_path(EDIT_URL_PREFIX + r'submission-tags/$',
views.SubmissionTagListView.as_view(),
name='course-submission-tags'),
re_path(EDIT_URL_PREFIX + r'submission-tags/new/$',
views.SubmissionTagAddView.as_view(),
name='course-submission-tags-add'),
re_path(EDIT_URL_PREFIX + r'submission-tags/(?P<tag_id>\d+)/edit$',
views.SubmissionTagEditView.as_view(),
name='course-submission-tags-edit'),
re_path(EDIT_URL_PREFIX + r'submission-tags/(?P<tag_id>\d+)/remove$',
views.SubmissionTagDeleteView.as_view(),
name='course-submission-tags-remove'),
re_path(EDIT_URL_PREFIX + r'batch-assess/$',
views.BatchCreateSubmissionsView.as_view(),
name='batch-assess'),
Expand Down
39 changes: 38 additions & 1 deletion edit_course/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
from exercise.cache.hierarchy import NoSuchContent
from exercise.models import LearningObject
from .course_forms import CourseInstanceForm, CourseIndexForm, \
CourseContentForm, CloneInstanceForm, GitmanagerForm, UserTagForm, SelectUsersForm
CourseContentForm, CloneInstanceForm, GitmanagerForm, UserTagForm, SelectUsersForm, SubmissionTagForm, \
SubmissionTaggingForm
from .managers import CategoryManager, ModuleManager, ExerciseManager
from .operations.batch import create_submissions
from .operations.configure import configure_from_url, get_build_log
Expand Down Expand Up @@ -302,6 +303,42 @@ def form_valid(self, form):
return super().form_valid(form)


class SubmissionTagMixin(CourseInstanceMixin, BaseTemplateMixin, BaseViewMixin):
access_mode = ACCESS.TEACHER
form_class = SubmissionTagForm
pk_url_kwarg = "tag_id"
success_url_name = "course-submission-tags"

def get_success_url(self):
return self.instance.get_url(self.success_url_name)

def get_queryset(self):
return self.instance.submissiontags.all()


class SubmissionTagListView(SubmissionTagMixin, ListView):
template_name = "edit_course/submissiontag_list.html"


class SubmissionTagAddView(SubmissionTagMixin, CreateView):
template_name = "edit_course/submissiontag_add.html"

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
if 'instance' not in kwargs or not kwargs['instance']:
kwargs.update({'instance': self.form_class.get_base_object(self.instance)})
return kwargs


class SubmissionTagEditView(SubmissionTagMixin, UpdateView):
template_name = "edit_course/submissiontag_edit.html"


class SubmissionTagDeleteView(SubmissionTagMixin, DeleteView):
form_class = Form
template_name = "edit_course/submissiontag_delete.html"


class BatchCreateSubmissionsView(CourseInstanceMixin, BaseTemplateView):
access_mode = ACCESS.TEACHER
template_name = "edit_course/batch_assess.html"
Expand Down
1 change: 1 addition & 0 deletions exercise/staff_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def get_common_objects(self) -> None:
self.lowest_visible_index = self.index - 10
self.highest_visible_index = self.index + 10

print(str(self.instance.submissiontags.all())) #REMOVE THIS LINE
# Find out if there are other submissions that the user should be
# notified about (better submissions, later submissions or the final
# submission).
Expand Down
Loading

0 comments on commit d43a3b0

Please sign in to comment.