Calculate competence certificate grades over all course sessions

This commit is contained in:
Elia Bieri 2024-07-25 11:04:32 +02:00
parent a6a83e6b90
commit 125d3b2b14
3 changed files with 46 additions and 22 deletions

View File

@ -693,15 +693,18 @@ export function useCourseStatisticsv2(courseSlug: string) {
}; };
} }
export function useCertificateQuery(userId: string | undefined, courseSlug: string) { export function useCertificateQuery(
userId: string | undefined,
courseSlug: string,
courseSession: CourseSession
) {
const certificatesQuery = (() => { const certificatesQuery = (() => {
const courseSession = useCurrentCourseSession();
if (userId) { if (userId) {
return useQuery({ return useQuery({
query: COMPETENCE_NAVI_CERTIFICATE_FOR_USER_QUERY, query: COMPETENCE_NAVI_CERTIFICATE_FOR_USER_QUERY,
variables: { variables: {
courseSlug: courseSlug, courseSlug: courseSlug,
courseSessionId: courseSession.value.id, courseSessionId: courseSession.id,
userId: userId, userId: userId,
}, },
}); });
@ -710,7 +713,7 @@ export function useCertificateQuery(userId: string | undefined, courseSlug: stri
query: COMPETENCE_NAVI_CERTIFICATE_QUERY, query: COMPETENCE_NAVI_CERTIFICATE_QUERY,
variables: { variables: {
courseSlug: courseSlug, courseSlug: courseSlug,
courseSessionId: courseSession.value.id, courseSessionId: courseSession.id,
}, },
}); });
} }

View File

@ -2,7 +2,7 @@
import log from "loglevel"; import log from "loglevel";
import { computed } from "vue"; import { computed } from "vue";
import type { CompetenceCertificate } from "@/types"; import type { CompetenceCertificate } from "@/types";
import { useCertificateQuery } from "@/composables"; import { useCertificateQuery, useCurrentCourseSession } from "@/composables";
import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue"; import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue";
import { getCertificates } from "@/services/competence"; import { getCertificates } from "@/services/competence";
import { getPreviousRoute } from "@/router/history"; import { getPreviousRoute } from "@/router/history";
@ -15,9 +15,11 @@ const props = defineProps<{
log.debug("CompetenceCertificateDetailPage setup", props); log.debug("CompetenceCertificateDetailPage setup", props);
const courseSession = useCurrentCourseSession();
const certificatesQuery = useCertificateQuery( const certificatesQuery = useCertificateQuery(
props.userId, props.userId,
props.courseSlug props.courseSlug,
courseSession.value
).certificatesQuery; ).certificatesQuery;
const certificate = computed(() => { const certificate = computed(() => {

View File

@ -2,7 +2,7 @@
import log from "loglevel"; import log from "loglevel";
import { computed, onMounted } from "vue"; import { computed, onMounted } from "vue";
import type { CompetenceCertificate } from "@/types"; import type { CompetenceCertificate } from "@/types";
import { useCertificateQuery } from "@/composables"; import { useCertificateQuery, useCurrentCourseSession } from "@/composables";
import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue"; import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue";
import { import {
assignmentsUserPoints, assignmentsUserPoints,
@ -10,6 +10,8 @@ import {
} from "@/pages/competence/utils"; } from "@/pages/competence/utils";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { getCertificates } from "@/services/competence"; import { getCertificates } from "@/services/competence";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import dayjs from "dayjs";
const props = defineProps<{ const props = defineProps<{
courseSlug: string; courseSlug: string;
@ -20,24 +22,41 @@ log.debug("CompetenceCertificateListPage setup", props);
const route = useRoute(); const route = useRoute();
const certificatesQuery = useCertificateQuery( const store = useCourseSessionsStore();
props.userId, const certificateQueries = store.allCourseSessions.map((courseSession) => {
props.courseSlug return useCertificateQuery(props.userId, props.courseSlug, courseSession)
).certificatesQuery; .certificatesQuery;
});
const competenceCertificates = computed(() => { const competenceCertificates = computed(() => {
const certificates = getCertificates( const competenceCertificates: Record<string, CompetenceCertificate> = {};
certificatesQuery.data.value, for (const query of certificateQueries) {
props.userId ?? null const certificates =
); (getCertificates(query.data.value, props.userId ?? null)
?.competence_certificates as unknown as CompetenceCertificate[]) ?? [];
if (!certificates) { for (const certificate of certificates) {
return null; if (!competenceCertificates[certificate.id]) {
// Competence certificate does not exist yet
competenceCertificates[certificate.id] = certificate;
} else {
// Merge with assignment completions of existing competence certificate. If there are multiple completions for the same assignment, keep the latest one.
competenceCertificates[certificate.id].assignments.push(
...certificate.assignments.filter((assignment) => {
const existingAssignment = competenceCertificates[
certificate.id
].assignments.find((a) => a.id === assignment.id);
return (
!existingAssignment ||
dayjs(assignment.completion?.evaluation_submitted_at).isAfter(
dayjs(existingAssignment.completion?.evaluation_submitted_at)
)
);
})
);
}
}
} }
return Object.values(competenceCertificates);
return (
(certificates?.competence_certificates as unknown as CompetenceCertificate[]) ?? []
);
}); });
const assignments = computed(() => { const assignments = computed(() => {