Refactor common code into composable

This commit is contained in:
Elia Bieri 2024-08-07 18:03:28 +02:00
parent 49a74a6d32
commit 8baecc0736
4 changed files with 53 additions and 71 deletions

View File

@ -32,6 +32,7 @@ import { useUserStore } from "@/stores/user";
import type { import type {
ActionCompetence, ActionCompetence,
CircleType, CircleType,
CompetenceCertificate,
Course, Course,
CourseCompletion, CourseCompletion,
CourseCompletionStatus, CourseCompletionStatus,
@ -52,6 +53,8 @@ import log from "loglevel";
import type { ComputedRef, Ref } from "vue"; import type { ComputedRef, Ref } from "vue";
import { computed, onMounted, ref, watchEffect } from "vue"; import { computed, onMounted, ref, watchEffect } from "vue";
import { useRouter, type RouteLocationRaw } from "vue-router"; import { useRouter, type RouteLocationRaw } from "vue-router";
import { getCertificates } from "./services/competence";
import { mergeCompetenceCertificates } from "./pages/competence/utils";
export function useCurrentCourseSession() { export function useCurrentCourseSession() {
/** /**
@ -746,3 +749,30 @@ export function useVVByLink() {
return { href }; return { href };
} }
export function useAllCompetenceCertificates(
userId: string | undefined,
courseSlug: string
) {
const courseSessionsStore = useCourseSessionsStore();
const certificateQueries = courseSessionsStore.allCourseSessions.map(
(courseSession) => {
return useCertificateQuery(userId, courseSlug, courseSession).certificatesQuery;
}
);
const competenceCertificatesPerCs = computed(() =>
certificateQueries.map((query) => {
return getCertificates(query.data.value, userId ?? null)
?.competence_certificates as unknown as CompetenceCertificate[];
})
);
const isLoaded = computed(() => !certificateQueries.some((q) => q.fetching.value));
const competenceCertificates = computed(() =>
mergeCompetenceCertificates(competenceCertificatesPerCs.value.flat())
);
return {
competenceCertificates,
isLoaded,
};
}

View File

@ -1,14 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import log from "loglevel"; import log from "loglevel";
import { computed } from "vue"; import { computed } from "vue";
import type { CompetenceCertificate } from "@/types"; import { useAllCompetenceCertificates } from "@/composables";
import { useCertificateQuery } from "@/composables";
import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue"; import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue";
import { getCertificates } from "@/services/competence";
import { getPreviousRoute } from "@/router/history"; import { getPreviousRoute } from "@/router/history";
import { mergeCompetenceCertificates } from "./utils";
import { useCourseSessionsStore } from "@/stores/courseSessions";
const props = defineProps<{ const props = defineProps<{
courseSlug: string; courseSlug: string;
certificateSlug: string; certificateSlug: string;
@ -17,24 +12,19 @@ const props = defineProps<{
log.debug("CompetenceCertificateDetailPage setup", props); log.debug("CompetenceCertificateDetailPage setup", props);
const store = useCourseSessionsStore(); const { competenceCertificates } = useAllCompetenceCertificates(
const certificateQueries = store.allCourseSessions.map((courseSession) => { props.userId,
return useCertificateQuery(props.userId, props.courseSlug, courseSession) props.courseSlug
.certificatesQuery; );
});
const certificate = computed(() => { const certificate = computed(() => {
const competenceCertificatesPerCs = certificateQueries.map((query) => { if (!competenceCertificates) {
return getCertificates(query.data.value, props.userId!)
?.competence_certificates as unknown as CompetenceCertificate[];
});
const certificates = mergeCompetenceCertificates(competenceCertificatesPerCs.flat());
if (!certificates) {
return null; return null;
} }
return certificates.find((cc) => cc.slug.endsWith(props.certificateSlug)); return competenceCertificates.value.find((cc) =>
cc.slug.endsWith(props.certificateSlug)
);
}); });
</script> </script>

View File

@ -1,18 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import log from "loglevel"; import log from "loglevel";
import { computed, onMounted } from "vue"; import { computed, onMounted } from "vue";
import type { CompetenceCertificate } from "@/types"; import { useAllCompetenceCertificates } from "@/composables";
import { useCertificateQuery } from "@/composables";
import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue"; import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue";
import { import {
assignmentsUserPoints, assignmentsUserPoints,
calcCompetencesTotalGrade, calcCompetencesTotalGrade,
mergeCompetenceCertificates,
} from "@/pages/competence/utils"; } from "@/pages/competence/utils";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { getCertificates } from "@/services/competence";
import { useCourseSessionsStore } from "@/stores/courseSessions";
const props = defineProps<{ const props = defineProps<{
courseSlug: string; courseSlug: string;
userId?: string; userId?: string;
@ -22,30 +17,17 @@ log.debug("CompetenceCertificateListPage setup", props);
const route = useRoute(); const route = useRoute();
const store = useCourseSessionsStore(); const { competenceCertificates } = useAllCompetenceCertificates(
console.log( props.userId,
`Loading competence certificates from ${store.allCourseSessions.length} course sessions:`, props.courseSlug
store.allCourseSessions.map((cs) => cs.title)
); );
const certificateQueries = store.allCourseSessions.map((courseSession) => {
return useCertificateQuery(props.userId, props.courseSlug, courseSession)
.certificatesQuery;
});
const mergedCertificates = computed(() => {
const competenceCertificatesPerCs = certificateQueries.map((query) => {
return getCertificates(query.data.value, props.userId ?? null)
?.competence_certificates as unknown as CompetenceCertificate[];
});
return mergeCompetenceCertificates(competenceCertificatesPerCs.flat());
});
const assignments = computed(() => { const assignments = computed(() => {
return mergedCertificates?.value?.flatMap((cc) => cc.assignments); return competenceCertificates?.value.flatMap((cc) => cc.assignments);
}); });
const totalGrade = computed(() => { const totalGrade = computed(() => {
return calcCompetencesTotalGrade(mergedCertificates.value ?? []); return calcCompetencesTotalGrade(competenceCertificates.value ?? []);
}); });
const userPointsEvaluatedAssignments = computed(() => { const userPointsEvaluatedAssignments = computed(() => {
@ -102,7 +84,7 @@ onMounted(async () => {
</div> </div>
<div <div
v-for="competenceCertificate in mergedCertificates" v-for="competenceCertificate in competenceCertificates"
:key="competenceCertificate.id" :key="competenceCertificate.id"
> >
<CompetenceCertificateComponent <CompetenceCertificateComponent

View File

@ -1,21 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import log from "loglevel"; import log from "loglevel";
import { computed } from "vue"; import { computed } from "vue";
import type { CompetenceCertificate } from "@/types"; import { useAllCompetenceCertificates, useCurrentCourseSession } from "@/composables";
import { useCertificateQuery, useCurrentCourseSession } from "@/composables";
import { import {
assignmentsUserPoints, assignmentsUserPoints,
calcCompetenceCertificateGrade, calcCompetenceCertificateGrade,
calcCompetencesTotalGrade, calcCompetencesTotalGrade,
competenceCertificateProgressStatusCount, competenceCertificateProgressStatusCount,
mergeCompetenceCertificates,
} from "@/pages/competence/utils"; } from "@/pages/competence/utils";
import ItProgress from "@/components/ui/ItProgress.vue"; import ItProgress from "@/components/ui/ItProgress.vue";
import SelfEvaluationAndFeedbackOverview from "@/components/selfEvaluationFeedback/SelfEvaluationAndFeedbackOverview.vue"; import SelfEvaluationAndFeedbackOverview from "@/components/selfEvaluationFeedback/SelfEvaluationAndFeedbackOverview.vue";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import { getCertificates } from "@/services/competence";
const props = defineProps<{ const props = defineProps<{
courseSlug: string; courseSlug: string;
@ -23,27 +19,13 @@ const props = defineProps<{
log.debug("CompetenceIndexPage setup", props); log.debug("CompetenceIndexPage setup", props);
const store = useCourseSessionsStore(); const { competenceCertificates, isLoaded } = useAllCompetenceCertificates(
console.log( undefined,
`Loading competence certificates from ${store.allCourseSessions.length} course sessions:`, props.courseSlug
store.allCourseSessions.map((cs) => cs.title)
); );
const certificateQueries = store.allCourseSessions.map((courseSession) => {
return useCertificateQuery(undefined, props.courseSlug, courseSession)
.certificatesQuery;
});
const mergedCertificates = computed(() => {
const competenceCertificatesPerCs = certificateQueries.map((query) => {
return getCertificates(query.data.value, null)
?.competence_certificates as unknown as CompetenceCertificate[];
});
return mergeCompetenceCertificates(competenceCertificatesPerCs.flat());
});
const allAssignments = computed(() => { const allAssignments = computed(() => {
return mergedCertificates.value.flatMap((cc) => cc.assignments); return competenceCertificates.value.flatMap((cc) => cc.assignments);
}); });
const userPointsEvaluatedAssignments = computed(() => { const userPointsEvaluatedAssignments = computed(() => {
@ -52,8 +34,6 @@ const userPointsEvaluatedAssignments = computed(() => {
const currentCourseSession = useCurrentCourseSession(); const currentCourseSession = useCurrentCourseSession();
const isLoaded = computed(() => !certificateQueries.some((q) => q.fetching.value));
const router = useRouter(); const router = useRouter();
</script> </script>
@ -71,7 +51,7 @@ const router = useRouter();
<div v-if="userPointsEvaluatedAssignments > 0"> <div v-if="userPointsEvaluatedAssignments > 0">
{{ $t("a.Erfahrungsnote üK") }}: {{ $t("a.Erfahrungsnote üK") }}:
<span class="font-bold"> <span class="font-bold">
{{ calcCompetencesTotalGrade(mergedCertificates ?? []) }} {{ calcCompetencesTotalGrade(competenceCertificates ?? []) }}
</span> </span>
<span class="rounded-full bg-gray-200 px-2.5 py-0.5 text-sm lg:ml-2"> <span class="rounded-full bg-gray-200 px-2.5 py-0.5 text-sm lg:ml-2">
@ -86,7 +66,7 @@ const router = useRouter();
<div> <div>
<div class="mt-4"> <div class="mt-4">
<div <div
v-for="certificate in mergedCertificates" v-for="certificate in competenceCertificates"
:key="certificate.id" :key="certificate.id"
class="flex flex-col justify-between py-4 lg:flex-row lg:items-center" class="flex flex-col justify-between py-4 lg:flex-row lg:items-center"
:data-cy="`certificate-${certificate.slug}`" :data-cy="`certificate-${certificate.slug}`"