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 30, 2024
1 parent ce46d6f commit b108411
Show file tree
Hide file tree
Showing 22 changed files with 736 additions and 8 deletions.
84 changes: 84 additions & 0 deletions course/migrations/0059_submissiontag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Generated by Django 4.2.11 on 2024-04-24 11:06

import colorfield
from django.db import migrations, models
import django.db.models.deletion
import lib.models


class Migration(migrations.Migration):

dependencies = [
("course", "0058_coursemodule_model_answer_and_more"),
]

operations = [
migrations.CreateModel(
name="SubmissionTag",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"name",
models.CharField(help_text="Display name for tag", max_length=20),
),
(
"slug",
models.SlugField(
help_text="Slug key for tag. If left blank, one is created from name",
max_length=20,
),
),
(
"description",
models.CharField(
blank=True,
help_text="Describe the usage or meaning of this tag",
max_length=155,
),
),
(
"color",
colorfield.ColorField(
default="#CD0000",
help_text="Color that is used as background for this tag",
max_length=7,
),
),
(
"visible_to_students",
models.BooleanField(
default=False, verbose_name="LABEL_VISIBLE_TO_STUDENTS"
),
),
(
"filter_status",
models.BooleanField(
default=False, verbose_name="LABEL_FILTER_STATUS"
),
),
(
"course_instance",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="submissiontags",
to="course.courseinstance",
verbose_name="LABEL_COURSE_INSTANCE",
),
),
],
options={
"verbose_name": "MODEL_NAME_SUBMISSION_TAG",
"verbose_name_plural": "MODEL_NAME_SUBMISSION_TAG_PLURAL",
"ordering": ["course_instance", "name"],
},
bases=(lib.models.UrlMixin, models.Model),
),
]
17 changes: 17 additions & 0 deletions course/migrations/0060_remove_submissiontag_filter_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.11 on 2024-04-24 11:13

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("course", "0059_submissiontag"),
]

operations = [
migrations.RemoveField(
model_name="submissiontag",
name="filter_status",
),
]
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 = ['id']

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_NEW_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-submission-tags' }}">{% translate "SUBMISSION_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 "SUBMISSION_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 %}
Loading

0 comments on commit b108411

Please sign in to comment.