From 5d7898d415ba8bff61752e8bf28e920ad801e062 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 23 Apr 2024 11:02:43 +0200 Subject: [PATCH] wip: Update copy, fix typecheck --- .../dashboard/MentorMenteeCount.vue | 4 +-- client/src/composables.ts | 2 +- client/src/gql/graphql.ts | 1 + client/src/gql/schema.graphql | 1 + .../CompetenceCertificateDetailPage.vue | 35 ++++++++++++++----- .../CompetenceCertificateListPage.vue | 28 ++++++++++++--- .../userProfile/CompetenceProfilePage.vue | 17 ++++++++- client/src/services/competence.ts | 22 ++++++++++++ client/src/services/dashboard.ts | 2 +- client/src/types.ts | 2 ++ server/vbv_lernwelt/course/graphql/types.py | 1 + 11 files changed, 97 insertions(+), 18 deletions(-) diff --git a/client/src/components/dashboard/MentorMenteeCount.vue b/client/src/components/dashboard/MentorMenteeCount.vue index b221c240..4beac8cd 100644 --- a/client/src/components/dashboard/MentorMenteeCount.vue +++ b/client/src/components/dashboard/MentorMenteeCount.vue @@ -23,7 +23,7 @@ onMounted(async () => { :details-link="`/dashboard/persons`" data-cy="dashboard.mentor.competenceSummary" > - + diff --git a/client/src/composables.ts b/client/src/composables.ts index 1428e4e8..99003461 100644 --- a/client/src/composables.ts +++ b/client/src/composables.ts @@ -177,7 +177,7 @@ export function useCourseData(courseSlug: string) { log.error(result.error); } - course.value = result.data?.course as Course; + course.value = result.data?.course as unknown as Course; actionCompetences.value = result.data?.course ?.action_competences as ActionCompetence[]; learningPath.value = result.data?.course?.learning_path as LearningPathType; diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 0dd382f2..ea49df2e 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -348,6 +348,7 @@ export type CourseConfigurationObjectType = { enable_learning_mentor: Scalars['Boolean']['output']; id: Scalars['ID']['output']; is_uk: Scalars['Boolean']['output']; + is_vv: Scalars['Boolean']['output']; }; export type CourseObjectType = { diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index ac20748c..8aa5b9ed 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -231,6 +231,7 @@ type CourseConfigurationObjectType { enable_circle_documents: Boolean! enable_learning_mentor: Boolean! enable_competence_certificates: Boolean! + is_vv: Boolean! is_uk: Boolean! } diff --git a/client/src/pages/competence/CompetenceCertificateDetailPage.vue b/client/src/pages/competence/CompetenceCertificateDetailPage.vue index 46814d2c..33c098ad 100644 --- a/client/src/pages/competence/CompetenceCertificateDetailPage.vue +++ b/client/src/pages/competence/CompetenceCertificateDetailPage.vue @@ -9,6 +9,10 @@ import { computed, onMounted } from "vue"; import type { CompetenceCertificate } from "@/types"; import { useCurrentCourseSession } from "@/composables"; import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertificateComponent.vue"; +import { + isCompetenceCertificateForUserQueryQuery, + isCompetenceCertificateQueryQuery, +} from "@/services/competence"; const props = defineProps<{ courseSlug: string; @@ -42,15 +46,30 @@ const certificatesQuery = (() => { })(); const certificate = computed(() => { - const certificate = props.userId - ? certificatesQuery.data?.value?.competence_certificate_list_for_user - : certificatesQuery.data?.value?.competence_certificate_list; - if (certificate) { - return ( - (certificate.competence_certificates as unknown as CompetenceCertificate[]) ?? [] - ).find((cc) => cc.slug.endsWith(props.certificateSlug)); + const data = certificatesQuery.data.value; + if (!data) { + return null; } - return null; + + let certificate; + + if (props.userId && isCompetenceCertificateForUserQueryQuery(data)) { + certificate = data.competence_certificate_list_for_user; + } else if (isCompetenceCertificateQueryQuery(data)) { + certificate = data.competence_certificate_list; + } else { + // Handle case where data does not match expected types + console.error("Data structure is not recognized!"); + return null; + } + + if (!certificate) { + return null; + } + + return ( + (certificate.competence_certificates as unknown as CompetenceCertificate[]) ?? [] + ).find((cc) => cc.slug.endsWith(props.certificateSlug)); }); onMounted(async () => { diff --git a/client/src/pages/competence/CompetenceCertificateListPage.vue b/client/src/pages/competence/CompetenceCertificateListPage.vue index c616082d..c1727b9c 100644 --- a/client/src/pages/competence/CompetenceCertificateListPage.vue +++ b/client/src/pages/competence/CompetenceCertificateListPage.vue @@ -14,6 +14,10 @@ import { assignmentsUserPoints, } from "@/pages/competence/utils"; import { useRoute } from "vue-router"; +import { + isCompetenceCertificateForUserQueryQuery, + isCompetenceCertificateQueryQuery, +} from "@/services/competence"; const props = defineProps<{ courseSlug: string; @@ -47,16 +51,30 @@ const certificatesQuery = (() => { })(); const competenceCertificates = computed(() => { - const certificates = props.userId - ? certificatesQuery.data?.value?.competence_certificate_list_for_user - : certificatesQuery.data?.value?.competence_certificate_list; + const data = certificatesQuery.data.value; + if (!data) { + return []; + } + + let certificate; + + if (props.userId && isCompetenceCertificateForUserQueryQuery(data)) { + certificate = data.competence_certificate_list_for_user; + } else if (isCompetenceCertificateQueryQuery(data)) { + certificate = data.competence_certificate_list; + } else { + // Handle case where data does not match expected types + console.error("Data structure is not recognized!"); + return []; + } + return ( - (certificates?.competence_certificates as unknown as CompetenceCertificate[]) ?? [] + (certificate?.competence_certificates as unknown as CompetenceCertificate[]) ?? [] ); }); const assignments = computed(() => { - return competenceCertificates.value.flatMap((cc) => cc.assignments); + return competenceCertificates?.value?.flatMap((cc) => cc.assignments); }); const totalPointsEvaluatedAssignments = computed(() => { diff --git a/client/src/pages/userProfile/CompetenceProfilePage.vue b/client/src/pages/userProfile/CompetenceProfilePage.vue index 4b0a50cd..58fdb156 100644 --- a/client/src/pages/userProfile/CompetenceProfilePage.vue +++ b/client/src/pages/userProfile/CompetenceProfilePage.vue @@ -50,6 +50,21 @@ if (useCurrentCourseSession().value.course.configuration.is_uk) { ); } +function convertRouteRecordNameToString( + routeRecordName: string | symbol | undefined +): string { + if (!routeRecordName) { + return ""; + } + if (typeof routeRecordName === "symbol") { + // Convert symbol to string explicitly + return routeRecordName.toString(); + } else { + // It's already a string, return as is + return routeRecordName; + } +} + const route = useRoute(); @@ -66,7 +81,7 @@ const route = useRoute(); class="flex w-full items-center space-x-2 p-2 pr-4 text-blue-900 hover:bg-gray-200 lg:pr-8" :class="{ 'text-bold bg-gray-200': route.matched.some((record) => - entry.routeMatch.includes(record.name) + entry.routeMatch.includes(convertRouteRecordNameToString(record?.name)) ), }" > diff --git a/client/src/services/competence.ts b/client/src/services/competence.ts index fd8e70a6..f2ec7b91 100644 --- a/client/src/services/competence.ts +++ b/client/src/services/competence.ts @@ -1,3 +1,7 @@ +import type { + CompetenceCertificateForUserQueryQuery, + CompetenceCertificateQueryQuery, +} from "@/gql/graphql"; import type { PerformanceCriteria } from "@/types"; import groupBy from "lodash/groupBy"; @@ -17,3 +21,21 @@ export function calcPerformanceCriteriaStatusCount(criteria: PerformanceCriteria FAIL: 0, }; } + +// Type guards +export function isCompetenceCertificateForUserQueryQuery( + data: any +): data is CompetenceCertificateForUserQueryQuery { + return ( + (data as CompetenceCertificateForUserQueryQuery) + .competence_certificate_list_for_user !== undefined + ); +} + +export function isCompetenceCertificateQueryQuery( + data: any +): data is CompetenceCertificateQueryQuery { + return ( + (data as CompetenceCertificateQueryQuery).competence_certificate_list !== undefined + ); +} diff --git a/client/src/services/dashboard.ts b/client/src/services/dashboard.ts index 8367824f..26dfb485 100644 --- a/client/src/services/dashboard.ts +++ b/client/src/services/dashboard.ts @@ -121,7 +121,7 @@ export const fetchDashboardConfig = async (): Promise