Fix loading of DueDates
This commit is contained in:
parent
dcf450339d
commit
227e9f317d
|
|
@ -17,7 +17,7 @@ const assignmentType = t(props.dueDate.assignment_type_translation_key);
|
||||||
|
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
const courseSessionsStore = useCourseSessionsStore();
|
||||||
const courseSession = courseSessionsStore.allCourseSessions.find(
|
const courseSession = courseSessionsStore.allCourseSessions.find(
|
||||||
(cs: CourseSession) => cs.id === props.dueDate.course_session
|
(cs: CourseSession) => cs.id === props.dueDate.course_session_id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!courseSession) {
|
if (!courseSession) {
|
||||||
|
|
@ -28,10 +28,10 @@ const isExpert = courseSessionsStore.hasCockpit(courseSession);
|
||||||
const url = isExpert ? props.dueDate.url_expert : props.dueDate.url;
|
const url = isExpert ? props.dueDate.url_expert : props.dueDate.url;
|
||||||
|
|
||||||
const courseSessionTitle = computed(() => {
|
const courseSessionTitle = computed(() => {
|
||||||
if (props.dueDate.course_session) {
|
if (props.dueDate.course_session_id) {
|
||||||
return (
|
return (
|
||||||
courseSessionsStore.getCourseSessionById(props.dueDate.course_session)?.title ??
|
courseSessionsStore.getCourseSessionById(props.dueDate.course_session_id)
|
||||||
""
|
?.title ?? ""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ onMounted(() => {
|
||||||
<template v-if="courseSessionsStore.currentCourseSessionHasCockpit">
|
<template v-if="courseSessionsStore.currentCourseSessionHasCockpit">
|
||||||
<router-link
|
<router-link
|
||||||
data-cy="navigation-cockpit-link"
|
data-cy="navigation-cockpit-link"
|
||||||
:to="`${courseSessionsStore.currentCourseSession.course_url}/cockpit`"
|
:to="`${courseSessionsStore.currentCourseSession.course.slug}/cockpit`"
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
:class="{ 'nav-item--active': inCockpit() }"
|
:class="{ 'nav-item--active': inCockpit() }"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const courseSessionsStore = useCourseSessionsStore();
|
||||||
<li class="mb-6">
|
<li class="mb-6">
|
||||||
<button
|
<button
|
||||||
data-cy="navigation-mobile-cockpit-link"
|
data-cy="navigation-mobile-cockpit-link"
|
||||||
@click="clickLink(`${courseSession.course_url}/cockpit`)"
|
@click="clickLink(`${courseSession.course.slug}/cockpit`)"
|
||||||
>
|
>
|
||||||
{{ $t("cockpit.title") }}
|
{{ $t("cockpit.title") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -101,14 +101,14 @@ const appointments = computed(() => {
|
||||||
|
|
||||||
const isMatchingSession = (dueDate: DueDate) =>
|
const isMatchingSession = (dueDate: DueDate) =>
|
||||||
selectedSession.value.id === UNFILTERED ||
|
selectedSession.value.id === UNFILTERED ||
|
||||||
dueDate.course_session === selectedSession.value.id;
|
dueDate.course_session_id === selectedSession.value.id;
|
||||||
|
|
||||||
const isMatchingCircle = (dueDate: DueDate) =>
|
const isMatchingCircle = (dueDate: DueDate) =>
|
||||||
selectedCircle.value.id === UNFILTERED ||
|
selectedCircle.value.id === UNFILTERED ||
|
||||||
dueDate.circle?.id === selectedCircle.value.id;
|
dueDate.circle?.id === selectedCircle.value.id;
|
||||||
|
|
||||||
const isMatchingCourse = (dueDate: DueDate) =>
|
const isMatchingCourse = (dueDate: DueDate) =>
|
||||||
courseSessions.value.map((cs) => cs.id).includes(dueDate.course_session);
|
courseSessions.value.map((cs) => cs.id).includes(dueDate.course_session_id);
|
||||||
|
|
||||||
const numAppointmentsToShow = ref(7);
|
const numAppointmentsToShow = ref(7);
|
||||||
const canLoadMore = computed(() => {
|
const canLoadMore = computed(() => {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const allDueDates = courseSessionsStore.allDueDates();
|
||||||
const getNextStepLink = (courseSession: CourseSession) => {
|
const getNextStepLink = (courseSession: CourseSession) => {
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
if (courseSessionsStore.hasCockpit(courseSession)) {
|
if (courseSessionsStore.hasCockpit(courseSession)) {
|
||||||
return `${courseSession.course_url}/cockpit`;
|
return `${courseSession.course.slug}/cockpit`;
|
||||||
}
|
}
|
||||||
return getLearningPathUrl(courseSession.course.slug);
|
return getLearningPathUrl(courseSession.course.slug);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -518,7 +518,6 @@ export interface CourseSession {
|
||||||
title: string;
|
title: string;
|
||||||
start_date: string;
|
start_date: string;
|
||||||
end_date: string;
|
end_date: string;
|
||||||
course_url: string;
|
|
||||||
due_dates: DueDate[];
|
due_dates: DueDate[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -672,5 +671,6 @@ export type DueDate = SimpleDueDate & {
|
||||||
subtitle: string;
|
subtitle: string;
|
||||||
url: string;
|
url: string;
|
||||||
url_expert: string;
|
url_expert: string;
|
||||||
|
course_session_id: string;
|
||||||
circle: CircleLight | null;
|
circle: CircleLight | null;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -53,20 +53,14 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
id = StringIDField()
|
id = StringIDField()
|
||||||
|
|
||||||
course = serializers.SerializerMethodField()
|
course = serializers.SerializerMethodField()
|
||||||
course_url = serializers.SerializerMethodField()
|
# course_url = serializers.SerializerMethodField()
|
||||||
due_dates = serializers.SerializerMethodField()
|
due_dates = serializers.SerializerMethodField()
|
||||||
|
|
||||||
def get_course(self, obj):
|
def get_course(self, obj):
|
||||||
return CourseSerializer(obj.course).data
|
return CourseSerializer(obj.course).data
|
||||||
|
|
||||||
def get_course_url(self, obj):
|
# def get_course_url(self, obj):
|
||||||
return obj.course.get_course_url()
|
# return obj.course.get_course_url()
|
||||||
|
|
||||||
def get_documents(self, obj):
|
|
||||||
documents = CircleDocument.objects.filter(
|
|
||||||
course_session=obj, file__upload_finished_at__isnull=False
|
|
||||||
)
|
|
||||||
return CircleDocumentSerializer(documents, many=True).data
|
|
||||||
|
|
||||||
def get_due_dates(self, obj):
|
def get_due_dates(self, obj):
|
||||||
due_dates = DueDate.objects.filter(course_session=obj)
|
due_dates = DueDate.objects.filter(course_session=obj)
|
||||||
|
|
@ -82,7 +76,6 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
"title",
|
"title",
|
||||||
"start_date",
|
"start_date",
|
||||||
"end_date",
|
"end_date",
|
||||||
"course_url",
|
|
||||||
"due_dates",
|
"due_dates",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 3.2.20 on 2023-10-10 13:05
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("duedate", "0005_auto_20230925_1648"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="duedate",
|
||||||
|
name="circle_data",
|
||||||
|
field=models.JSONField(blank=True, default=dict),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Generated by Django 3.2.20 on 2023-10-10 13:05
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db.migrations import RunPython
|
||||||
|
|
||||||
|
|
||||||
|
def trigger_due_date_save(apps, schema_editor):
|
||||||
|
# need to load concrete model, so that wagtail page has `specific` instance method...
|
||||||
|
from vbv_lernwelt.duedate.models import DueDate
|
||||||
|
|
||||||
|
for due_date in DueDate.objects.all():
|
||||||
|
# trigger save to prefetch circle data
|
||||||
|
due_date.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("duedate", "0006_duedate_circle_data"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [RunPython(trigger_due_date_save)]
|
||||||
|
|
@ -60,6 +60,7 @@ class DueDate(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True, blank=True)
|
page = models.ForeignKey(Page, on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
circle_data = models.JSONField(default=dict, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["start", "end"]
|
ordering = ["start", "end"]
|
||||||
|
|
@ -80,6 +81,21 @@ class DueDate(models.Model):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
circle = self.get_circle()
|
||||||
|
# prefetch circle data, because loading it dynamically is too slow
|
||||||
|
if circle:
|
||||||
|
self.circle_data = {
|
||||||
|
"id": str(circle.id),
|
||||||
|
"title": circle.title,
|
||||||
|
"slug": circle.slug,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
# noop
|
||||||
|
pass
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def display_subtitle(self):
|
def display_subtitle(self):
|
||||||
result = ""
|
result = ""
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,9 @@ from vbv_lernwelt.duedate.models import DueDate
|
||||||
|
|
||||||
class DueDateSerializer(serializers.ModelSerializer):
|
class DueDateSerializer(serializers.ModelSerializer):
|
||||||
id = StringIDField()
|
id = StringIDField()
|
||||||
|
course_session_id = serializers.SerializerMethodField()
|
||||||
circle = serializers.SerializerMethodField()
|
circle = serializers.SerializerMethodField()
|
||||||
|
|
||||||
# course_session = StringIDField()
|
|
||||||
# page = StringIDField()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = DueDate
|
model = DueDate
|
||||||
fields = [
|
fields = [
|
||||||
|
|
@ -24,18 +22,18 @@ class DueDateSerializer(serializers.ModelSerializer):
|
||||||
"subtitle",
|
"subtitle",
|
||||||
"url",
|
"url",
|
||||||
"url_expert",
|
"url_expert",
|
||||||
"course_session",
|
"course_session_id",
|
||||||
"page",
|
|
||||||
"circle",
|
"circle",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_circle(self, obj):
|
def get_course_session_id(self, obj):
|
||||||
circle = obj.get_circle()
|
return str(obj.course_session.id)
|
||||||
|
|
||||||
if circle:
|
def get_circle(self, obj):
|
||||||
|
if obj.circle_data:
|
||||||
return {
|
return {
|
||||||
"id": str(circle.id),
|
"id": obj.circle_data.get("id"),
|
||||||
"title": circle.title,
|
"title": obj.circle_data.get("title"),
|
||||||
"translation_key": circle.translation_key,
|
"slug": obj.circle_data.get("slug"),
|
||||||
}
|
}
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@ from django.db import migrations
|
||||||
def init_user_notification_emails(apps=None, schema_editor=None):
|
def init_user_notification_emails(apps=None, schema_editor=None):
|
||||||
User = apps.get_model("core", "User")
|
User = apps.get_model("core", "User")
|
||||||
for u in User.objects.all():
|
for u in User.objects.all():
|
||||||
u.additional_json_data["email_notification_categories"] = ["NOTIFICATION"]
|
u.additional_json_data["email_notification_categories"] = [
|
||||||
|
"INFORMATION",
|
||||||
|
"USER_INTERACTION",
|
||||||
|
]
|
||||||
u.save()
|
u.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue