VBV-514: Termine nur für ausgewählte Circles anzeigen im Cockpit
This commit is contained in:
parent
f5d44bcb90
commit
db40368244
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import { formatDate } from "@/components/dueDates/dueDatesUtils";
|
||||
import { formatDueDate } from "@/components/dueDates/dueDatesUtils";
|
||||
import type { DueDate } from "@/types";
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
@ -30,7 +30,7 @@ const props = defineProps<{
|
|||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{{ formatDate(props.dueDate.start, props.dueDate.end) }}
|
||||
{{ formatDueDate(props.dueDate.start, props.dueDate.end) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,38 +1,45 @@
|
|||
import type { Dayjs } from "dayjs";
|
||||
import dayjs from "dayjs";
|
||||
import LocalizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import i18next from "i18next";
|
||||
|
||||
export const formatDate = (start: Dayjs, end: Dayjs) => {
|
||||
const startDateString = getDateString(start);
|
||||
const endDateString = getDateString(end);
|
||||
export const formatDueDate = (start: string, end: string) => {
|
||||
dayjs.extend(LocalizedFormat);
|
||||
const startDayjs = dayjs(start);
|
||||
const endDayjs = dayjs(end);
|
||||
const startDateString = getDateString(startDayjs);
|
||||
const endDateString = getDateString(endDayjs);
|
||||
|
||||
// if start isundefined, dont show the day twice
|
||||
// if startDayjs isundefined, dont show the day twice
|
||||
|
||||
if (!start.isValid() && !end.isValid()) {
|
||||
if (!startDayjs.isValid() && !endDayjs.isValid()) {
|
||||
return i18next.t("Termin nicht festgelegt");
|
||||
}
|
||||
|
||||
if (!start || (!start.isValid() && end.isValid())) {
|
||||
return `${endDateString} ${getTimeString(end)} ${end.format("[Uhr]")}`;
|
||||
if (!startDayjs || (!startDayjs.isValid() && endDayjs.isValid())) {
|
||||
return `${endDateString} ${getTimeString(endDayjs)} ${endDayjs.format("[Uhr]")}`;
|
||||
}
|
||||
if (!end || (!end.isValid() && start.isValid())) {
|
||||
return `${startDateString} ${getTimeString(start)} ${start.format("[Uhr]")}`;
|
||||
if (!endDayjs || (!endDayjs.isValid() && startDayjs.isValid())) {
|
||||
return `${startDateString} ${getTimeString(startDayjs)} ${startDayjs.format(
|
||||
"[Uhr]"
|
||||
)}`;
|
||||
}
|
||||
|
||||
// if start and end are on the same day, dont show the day twice
|
||||
// if startDayjs and endDayjs are on the same day, dont show the day twice
|
||||
if (startDateString === endDateString) {
|
||||
return `${startDateString} ${getTimeString(start)} - ${getTimeString(
|
||||
end
|
||||
)} ${end.format("[Uhr]")}`;
|
||||
return `${startDateString} ${getTimeString(startDayjs)} - ${getTimeString(
|
||||
endDayjs
|
||||
)} ${endDayjs.format("[Uhr]")}`;
|
||||
}
|
||||
|
||||
return `${startDateString} ${getTimeString(start)} - ${endDateString} ${getTimeString(
|
||||
end
|
||||
)}`;
|
||||
return `${startDateString} ${getTimeString(
|
||||
startDayjs
|
||||
)} - ${endDateString} ${getTimeString(endDayjs)}`;
|
||||
};
|
||||
|
||||
export const getTimeString = (date?: Dayjs) => {
|
||||
if (date) {
|
||||
return `${date.format("H:mm")}`;
|
||||
return `${date.format("HH:mm")}`;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,22 +1,33 @@
|
|||
<script setup lang="ts">
|
||||
import { useCurrentCourseSession } from "@/composables";
|
||||
import DueDateSingle from "@/components/dueDates/DueDateSingle.vue";
|
||||
import { computed } from "vue";
|
||||
import { useCockpitStore } from "@/stores/cockpit";
|
||||
|
||||
const cockpitStore = useCockpitStore();
|
||||
const courseSession = useCurrentCourseSession();
|
||||
const dueDates = courseSession.value.due_dates.slice(0, 2);
|
||||
|
||||
const circleDates = computed(() => {
|
||||
const dueDates = courseSession.value.due_dates.filter((dueDate) => {
|
||||
return cockpitStore.selectedCircles.includes(
|
||||
dueDate?.circle?.translation_key ?? ""
|
||||
);
|
||||
});
|
||||
return dueDates.slice(0, 4);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col space-y-2">
|
||||
<h3 class="heading-3">{{ $t("Nächste Termine") }}</h3>
|
||||
<div
|
||||
v-for="dueDate in dueDates"
|
||||
v-for="dueDate in circleDates"
|
||||
:key="dueDate.id"
|
||||
class="border-t border-gray-500 pt-2"
|
||||
>
|
||||
<DueDateSingle :due-date="dueDate" :single-line="true"></DueDateSingle>
|
||||
</div>
|
||||
<div v-if="dueDates.length === 0">{{ $t("dueDates.noDueDatesAvailable") }}</div>
|
||||
<div v-if="circleDates.length === 0">{{ $t("dueDates.noDueDatesAvailable") }}</div>
|
||||
<a class="border-t border-gray-500 pt-8 underline" href="">
|
||||
{{ $t("dueDates.showAllDueDates") }}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
<div class="mb-12 grid grid-cols-icon-card gap-x-4 grid-areas-icon-card">
|
||||
<it-icon-calendar-light class="w-[60px] grid-in-icon" />
|
||||
<h2 class="text-large font-bold grid-in-title">{{ $t("a.Datum") }}</h2>
|
||||
<p class="grid-in-value">{{ formatDate(start, end) }}</p>
|
||||
<p class="grid-in-value">
|
||||
{{ formatDueDate(props.attendanceCourse.start, props.attendanceCourse.end) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="mb-12 grid grid-cols-icon-card gap-x-4 grid-areas-icon-card">
|
||||
<it-icon-location class="w-[60px] grid-in-icon" />
|
||||
|
|
@ -20,7 +22,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { formatDate } from "@/components/dueDates/dueDatesUtils";
|
||||
import { formatDueDate } from "@/components/dueDates/dueDatesUtils";
|
||||
import type { CourseSessionAttendanceCourse } from "@/types";
|
||||
import dayjs from "dayjs";
|
||||
import LocalizedFormat from "dayjs/plugin/localizedFormat";
|
||||
|
|
@ -33,8 +35,6 @@ export interface Props {
|
|||
const props = defineProps<Props>();
|
||||
|
||||
dayjs.extend(LocalizedFormat);
|
||||
const start = computed(() => dayjs(props.attendanceCourse.start));
|
||||
const end = computed(() => dayjs(props.attendanceCourse.end));
|
||||
const location = computed(() => props.attendanceCourse.location);
|
||||
const trainer = computed(() => props.attendanceCourse.trainer);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -40,10 +40,6 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
|||
reload: reload,
|
||||
})) as CourseSessionUser[];
|
||||
cs.users = users;
|
||||
cs.due_dates.forEach((dueDate) => {
|
||||
dueDate.start = dayjs(dueDate.start);
|
||||
dueDate.end = dayjs(dueDate.end);
|
||||
});
|
||||
sortDueDates(cs.due_dates);
|
||||
})
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { AssignmentCompletionStatus as AssignmentCompletionStatusGenerated } from "@/gql/graphql";
|
||||
import type { Circle } from "@/services/circle";
|
||||
import type { Dayjs } from "dayjs";
|
||||
import type { Component } from "vue";
|
||||
|
||||
export type LoginMethod = "local" | "sso";
|
||||
|
|
@ -624,8 +623,8 @@ export interface UserAssignmentCompletionStatus {
|
|||
|
||||
export type DueDate = {
|
||||
id: number;
|
||||
start: Dayjs;
|
||||
end: Dayjs;
|
||||
start: string;
|
||||
end: string;
|
||||
title: string;
|
||||
assignment_type_translation_key: string;
|
||||
date_type_translation_key: string;
|
||||
|
|
@ -633,4 +632,5 @@ export type DueDate = {
|
|||
url: string;
|
||||
course_session: number | null;
|
||||
page: number | null;
|
||||
circle: CircleLight | null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -103,6 +103,16 @@ class CourseBasePage(Page):
|
|||
return course_parent_page.specific.course
|
||||
return None
|
||||
|
||||
def get_circle(self):
|
||||
from vbv_lernwelt.learnpath.models import Circle
|
||||
|
||||
try:
|
||||
return self.get_ancestors().exact_type(Circle).first()
|
||||
except Exception:
|
||||
# noop
|
||||
pass
|
||||
return None
|
||||
|
||||
def get_circles(self):
|
||||
course_parent_page = self.get_course_parent()
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,13 @@ class DueDate(models.Model):
|
|||
return datetime.timedelta(0)
|
||||
return self.end - self.start
|
||||
|
||||
def get_circle(self):
|
||||
try:
|
||||
return self.page.specific.get_circle()
|
||||
except Exception:
|
||||
# noop
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_users_next_events_qs(
|
||||
cls, user: User, course_session: CourseSession = None, limit=10
|
||||
|
|
|
|||
|
|
@ -4,6 +4,30 @@ from vbv_lernwelt.duedate.models import DueDate
|
|||
|
||||
|
||||
class DueDateSerializer(serializers.ModelSerializer):
|
||||
circle = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = DueDate
|
||||
fields = "__all__"
|
||||
fields = [
|
||||
"start",
|
||||
"end",
|
||||
"manual_override_fields",
|
||||
"title",
|
||||
"assignment_type_translation_key",
|
||||
"date_type_translation_key",
|
||||
"subtitle",
|
||||
"url",
|
||||
"course_session",
|
||||
"page",
|
||||
"circle",
|
||||
]
|
||||
|
||||
def get_circle(self, obj):
|
||||
circle = obj.get_circle()
|
||||
if circle:
|
||||
return {
|
||||
"id": circle.id,
|
||||
"title": circle.title,
|
||||
"translation_key": circle.translation_key,
|
||||
}
|
||||
return None
|
||||
|
|
|
|||
Loading…
Reference in New Issue