VBV-459: Add flag for user course completion self toggle
This commit is contained in:
parent
3bd489d2ae
commit
1b7a3a401e
|
|
@ -138,6 +138,7 @@ const learningSequenceBorderClass = computed(() => {
|
||||||
value: learningContent.completion_status,
|
value: learningContent.completion_status,
|
||||||
checked: learningContent.completion_status === 'SUCCESS',
|
checked: learningContent.completion_status === 'SUCCESS',
|
||||||
}"
|
}"
|
||||||
|
:disabled="!learningContent.can_user_self_toggle_course_completion"
|
||||||
:data-cy="`${learningContent.slug}-checkbox`"
|
:data-cy="`${learningContent.slug}-checkbox`"
|
||||||
@toggle="toggleCompleted(learningContent)"
|
@toggle="toggleCompleted(learningContent)"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ export interface LearningContentInterface extends BaseCourseWagtailPage {
|
||||||
readonly minutes: number;
|
readonly minutes: number;
|
||||||
readonly description: string;
|
readonly description: string;
|
||||||
readonly content_url: string;
|
readonly content_url: string;
|
||||||
|
readonly can_user_self_toggle_course_completion: boolean;
|
||||||
parentCircle: Circle;
|
parentCircle: Circle;
|
||||||
parentLearningSequence?: LearningSequence;
|
parentLearningSequence?: LearningSequence;
|
||||||
parentLearningUnit?: LearningUnit;
|
parentLearningUnit?: LearningUnit;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 3.2.13 on 2023-06-26 15:47
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("competence", "0002_performancecriteria_learning_unit"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="performancecriteria",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="performancecriteria",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -75,6 +75,8 @@ class PerformanceCriteria(CourseBasePage):
|
||||||
blank=True,
|
blank=True,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
)
|
)
|
||||||
|
has_course_completion_status = models.BooleanField(default=True)
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("title"),
|
FieldPanel("title"),
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,15 @@ def mark_course_completion(
|
||||||
f"Invalid value for CourseCompletionStatus: {completion_status}"
|
f"Invalid value for CourseCompletionStatus: {completion_status}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: check if this page can be "marked" by user
|
if not (
|
||||||
|
hasattr(page.specific, "has_course_completion_status")
|
||||||
|
and page.specific.has_course_completion_status
|
||||||
|
):
|
||||||
|
return ValueError(
|
||||||
|
f"Page {page.id} of type {get_wagtail_type(page)}"
|
||||||
|
f" cannot be marked as completed"
|
||||||
|
)
|
||||||
|
|
||||||
cc, created = CourseCompletion.objects.get_or_create(
|
cc, created = CourseCompletion.objects.get_or_create(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
page_id=page.id,
|
page_id=page.id,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
# Generated by Django 3.2.13 on 2023-06-26 15:47
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("learnpath", "0007_learningunit_title_hidden"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentassignment",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentassignment",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentattendancecourse",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentattendancecourse",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentdocumentlist",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentdocumentlist",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentfeedback",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentfeedback",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentlearningmodule",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentlearningmodule",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentmedialibrary",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentmedialibrary",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentplaceholder",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentplaceholder",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentrichtext",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentrichtext",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontenttest",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontenttest",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentvideo",
|
||||||
|
name="can_user_self_toggle_course_completion",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="learningcontentvideo",
|
||||||
|
name="has_course_completion_status",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -234,17 +234,21 @@ class LearningContent(CourseBasePage):
|
||||||
"minutes",
|
"minutes",
|
||||||
"description",
|
"description",
|
||||||
"content_url",
|
"content_url",
|
||||||
|
"can_user_self_toggle_course_completion",
|
||||||
]
|
]
|
||||||
|
|
||||||
minutes = models.PositiveIntegerField(default=15)
|
minutes = models.PositiveIntegerField(default=15)
|
||||||
description = RichTextField(blank=True)
|
description = RichTextField(blank=True)
|
||||||
content_url = models.TextField(blank=True)
|
content_url = models.TextField(blank=True)
|
||||||
|
has_course_completion_status = models.BooleanField(default=True)
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=False)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("title", classname="full title"),
|
FieldPanel("title", classname="full title"),
|
||||||
FieldPanel("minutes"),
|
FieldPanel("minutes"),
|
||||||
FieldPanel("content_url"),
|
FieldPanel("content_url"),
|
||||||
FieldPanel("description"),
|
FieldPanel("description"),
|
||||||
|
FieldPanel("can_user_self_toggle_course_completion"),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_admin_display_title(self):
|
def get_admin_display_title(self):
|
||||||
|
|
@ -290,26 +294,31 @@ class LearningContentAttendanceCourse(LearningContent):
|
||||||
class LearningContentVideo(LearningContent):
|
class LearningContentVideo(LearningContent):
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
|
||||||
class LearningContentPlaceholder(LearningContent):
|
class LearningContentPlaceholder(LearningContent):
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
|
||||||
class LearningContentFeedback(LearningContent):
|
class LearningContentFeedback(LearningContent):
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
|
||||||
class LearningContentLearningModule(LearningContent):
|
class LearningContentLearningModule(LearningContent):
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
|
||||||
class LearningContentMediaLibrary(LearningContent):
|
class LearningContentMediaLibrary(LearningContent):
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
|
||||||
class LearningContentTest(LearningContent):
|
class LearningContentTest(LearningContent):
|
||||||
|
|
@ -328,6 +337,7 @@ class LearningContentTest(LearningContent):
|
||||||
|
|
||||||
class LearningContentRichText(LearningContent):
|
class LearningContentRichText(LearningContent):
|
||||||
text = RichTextField(blank=True, features=DEFAULT_RICH_TEXT_FEATURES_WITH_HEADER)
|
text = RichTextField(blank=True, features=DEFAULT_RICH_TEXT_FEATURES_WITH_HEADER)
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
parent_page_types = ["learnpath.Circle"]
|
parent_page_types = ["learnpath.Circle"]
|
||||||
serialize_field_names = LearningContent.serialize_field_names + [
|
serialize_field_names = LearningContent.serialize_field_names + [
|
||||||
|
|
@ -368,6 +378,8 @@ class LearningContentAssignment(LearningContent):
|
||||||
|
|
||||||
|
|
||||||
class LearningContentDocumentList(LearningContent):
|
class LearningContentDocumentList(LearningContent):
|
||||||
|
can_user_self_toggle_course_completion = models.BooleanField(default=True)
|
||||||
|
|
||||||
serialize_field_names = LearningContent.serialize_field_names + [
|
serialize_field_names = LearningContent.serialize_field_names + [
|
||||||
"documents",
|
"documents",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,12 @@ from vbv_lernwelt.learnpath.models import LearningUnit
|
||||||
class LearningUnitSerializer(
|
class LearningUnitSerializer(
|
||||||
get_course_serializer_class(
|
get_course_serializer_class(
|
||||||
LearningUnit,
|
LearningUnit,
|
||||||
field_names=["evaluate_url", "course_category", "children", "title_hidden"],
|
field_names=[
|
||||||
|
"evaluate_url",
|
||||||
|
"course_category",
|
||||||
|
"children",
|
||||||
|
"title_hidden",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
evaluate_url = SerializerMethodField()
|
evaluate_url = SerializerMethodField()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue