Add Grade widget in dashboard
This commit is contained in:
parent
29c42f3512
commit
e41b3222bf
|
|
@ -7,6 +7,8 @@ import {
|
||||||
import type { BaseStatisticsType } from "@/gql/graphql";
|
import type { BaseStatisticsType } from "@/gql/graphql";
|
||||||
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
|
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
|
||||||
import AssignmentSummaryBox from "@/components/dashboard/AssignmentSummaryBox.vue";
|
import AssignmentSummaryBox from "@/components/dashboard/AssignmentSummaryBox.vue";
|
||||||
|
import BaseBox from "@/components/dashboard/BaseBox.vue";
|
||||||
|
import { percentToRoundedGrade } from "@/services/assignmentService";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
courseSlug: string;
|
courseSlug: string;
|
||||||
|
|
@ -28,18 +30,48 @@ onMounted(async () => {
|
||||||
);
|
);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const averageGrade = computed(() => {
|
||||||
|
return percentToRoundedGrade(
|
||||||
|
assignmentStats.value?.summary.average_evaluation_percent ?? 0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="loading" class="m-8 flex justify-center">
|
<div v-if="loading" class="m-8 flex justify-center">
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="assignmentStats" class="space-y-8">
|
<div v-if="assignmentStats" class="w-full space-y-8">
|
||||||
<div
|
<div
|
||||||
class="flex flex-col flex-wrap justify-between gap-x-5 border-b border-gray-300 pb-8 last:border-0 md:flex-row"
|
class="flex flex-col flex-wrap justify-between gap-x-5 border-b border-gray-300 pb-8 last:border-0 md:flex-row"
|
||||||
>
|
>
|
||||||
|
<div class="flex-1">
|
||||||
|
<BaseBox
|
||||||
|
:details-link="`/statistic/berufsbildner/${props.courseSlug}/competence-grade`"
|
||||||
|
data-cy="dashboard.stats.competenceGrades"
|
||||||
|
>
|
||||||
|
<template #title>{{ $t("a.Kompetenznachweise") }}</template>
|
||||||
|
<template #content>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<div class="min-w-12 text-center">
|
||||||
|
<div
|
||||||
|
class="heading-2 rounded bg-green-500 p-4"
|
||||||
|
:class="{ 'bg-red-400': averageGrade < 4 }"
|
||||||
|
>
|
||||||
|
{{ averageGrade }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t("a.Durchschnittsnote") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</BaseBox>
|
||||||
|
</div>
|
||||||
<AssignmentSummaryBox
|
<AssignmentSummaryBox
|
||||||
class="flex-grow"
|
class="flex-1"
|
||||||
:assignments-completed="assignmentStats.summary.completed_count"
|
:assignments-completed="assignmentStats.summary.completed_count"
|
||||||
:avg-passed="assignmentStats.summary.average_passed"
|
:avg-passed="assignmentStats.summary.average_passed"
|
||||||
:course-slug="props.courseSlug"
|
:course-slug="props.courseSlug"
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,13 @@ const actionButtonProps = computed<{ href: string; text: string; cyKey: string }
|
||||||
cyKey: "lm-dashboard-link",
|
cyKey: "lm-dashboard-link",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (props.courseConfig?.role_key === "Berufsbildner") {
|
||||||
|
return {
|
||||||
|
href: getLearningPathUrl(props.courseConfig?.course_slug),
|
||||||
|
text: "a.Vorschau Teilnehmer",
|
||||||
|
cyKey: "progress-dashboard-continue-course-link",
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
href: getLearningPathUrl(props.courseConfig?.course_slug),
|
href: getLearningPathUrl(props.courseConfig?.course_slug),
|
||||||
text: "Weiter lernen",
|
text: "Weiter lernen",
|
||||||
|
|
@ -107,7 +114,7 @@ function hasActionButton(): boolean {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span>{{ $t("a.VorschauTeilnehmer") }}</span>
|
<span>{{ $t("a.Vorschau Teilnehmer") }}</span>
|
||||||
<it-icon-external-link class="ml-1 !h-4 !w-4" />
|
<it-icon-external-link class="ml-1 !h-4 !w-4" />
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ function getFilteredItems() {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex flex-col space-x-2 lg:flex-row border-b">
|
<div class="flex flex-col space-x-2 border-b lg:flex-row">
|
||||||
<ItDropdownSelect
|
<ItDropdownSelect
|
||||||
v-if="regionFilter.length > 2"
|
v-if="regionFilter.length > 2"
|
||||||
v-model="regionFilterValue"
|
v-model="regionFilterValue"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const { t } = useTranslation();
|
||||||
class="relative flex h-16 w-full flex-col items-center justify-end space-x-8 lg:flex-row lg:items-stretch lg:justify-center"
|
class="relative flex h-16 w-full flex-col items-center justify-end space-x-8 lg:flex-row lg:items-stretch lg:justify-center"
|
||||||
>
|
>
|
||||||
<span class="flex items-center px-1 pt-1 font-bold text-black">
|
<span class="flex items-center px-1 pt-1 font-bold text-black">
|
||||||
{{ t("a.VorschauTeilnehmer") }} ({{ courseSession.title }})
|
{{ t("a.Vorschau Teilnehmer") }} ({{ courseSession.title }})
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="flex space-x-8">
|
<div class="flex space-x-8">
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ const mentorTabTitle = computed(() =>
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span>{{ t("a.VorschauTeilnehmer") }}</span>
|
<span>{{ t("a.Vorschau Teilnehmer") }}</span>
|
||||||
<it-icon-external-link class="ml-2" />
|
<it-icon-external-link class="ml-2" />
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ const mentorTabTitle = computed(() =>
|
||||||
data-cy="navigation-mobile-preview-link"
|
data-cy="navigation-mobile-preview-link"
|
||||||
@click="clickLink(getLearningPathUrl(courseSession.course.slug))"
|
@click="clickLink(getLearningPathUrl(courseSession.course.slug))"
|
||||||
>
|
>
|
||||||
{{ $t("a.VorschauTeilnehmer") }}
|
{{ $t("a.Vorschau Teilnehmer") }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="hasLearningPathMenu" class="mb-6">
|
<li v-if="hasLearningPathMenu" class="mb-6">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const documents = {
|
||||||
"\n query dashboardProgress($courseId: ID!) {\n course_progress(course_id: $courseId) {\n _id\n course_id\n session_to_continue_id\n competence {\n _id\n total_count\n success_count\n fail_count\n }\n assignment {\n _id\n total_count\n points_max_count\n points_achieved_count\n }\n }\n }\n": types.DashboardProgressDocument,
|
"\n query dashboardProgress($courseId: ID!) {\n course_progress(course_id: $courseId) {\n _id\n course_id\n session_to_continue_id\n competence {\n _id\n total_count\n success_count\n fail_count\n }\n assignment {\n _id\n total_count\n points_max_count\n points_achieved_count\n }\n }\n }\n": types.DashboardProgressDocument,
|
||||||
"\n query dashboardCourseData($courseId: ID!) {\n course_progress(course_id: $courseId) {\n _id\n course_id\n session_to_continue_id\n }\n }\n": types.DashboardCourseDataDocument,
|
"\n query dashboardCourseData($courseId: ID!) {\n course_progress(course_id: $courseId) {\n _id\n course_id\n session_to_continue_id\n }\n }\n": types.DashboardCourseDataDocument,
|
||||||
"\n query courseStatistics($courseId: ID!) {\n course_statistics(course_id: $courseId) {\n _id\n course_id\n course_title\n course_slug\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n course_session_selection_ids\n course_session_selection_metrics {\n _id\n session_count\n participant_count\n expert_count\n }\n attendance_day_presences {\n _id\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n due_date\n participants_present\n participants_total\n details_url\n }\n summary {\n _id\n days_completed\n participants_present\n }\n }\n feedback_responses {\n _id\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n experts\n satisfaction_average\n satisfaction_max\n details_url\n }\n summary {\n _id\n satisfaction_average\n satisfaction_max\n total_responses\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_title\n competence_certificate_id\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_evaluation_percent\n average_passed\n competence_certificate_weight\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n title\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n": types.CourseStatisticsDocument,
|
"\n query courseStatistics($courseId: ID!) {\n course_statistics(course_id: $courseId) {\n _id\n course_id\n course_title\n course_slug\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n course_session_selection_ids\n course_session_selection_metrics {\n _id\n session_count\n participant_count\n expert_count\n }\n attendance_day_presences {\n _id\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n due_date\n participants_present\n participants_total\n details_url\n }\n summary {\n _id\n days_completed\n participants_present\n }\n }\n feedback_responses {\n _id\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n experts\n satisfaction_average\n satisfaction_max\n details_url\n }\n summary {\n _id\n satisfaction_average\n satisfaction_max\n total_responses\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_title\n competence_certificate_id\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_evaluation_percent\n average_passed\n competence_certificate_weight\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n title\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n": types.CourseStatisticsDocument,
|
||||||
"\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n": types.MentorCourseStatisticsDocument,
|
"\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n average_evaluation_percent\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n": types.MentorCourseStatisticsDocument,
|
||||||
"\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $learningContentType: String!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n learning_content_type: $learningContentType\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument,
|
"\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $learningContentType: String!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n learning_content_type: $learningContentType\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -94,7 +94,7 @@ export function graphql(source: "\n query courseStatistics($courseId: ID!) {\n
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(source: "\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n"];
|
export function graphql(source: "\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n average_evaluation_percent\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n average_evaluation_percent\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n"];
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -88,6 +88,7 @@ type AssignmentStatisticsSummaryType {
|
||||||
average_passed: Float!
|
average_passed: Float!
|
||||||
total_passed: Int!
|
total_passed: Int!
|
||||||
total_failed: Int!
|
total_failed: Int!
|
||||||
|
average_evaluation_percent: Float
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatisticsCourseSessionPropertiesType {
|
type StatisticsCourseSessionPropertiesType {
|
||||||
|
|
|
||||||
|
|
@ -511,6 +511,7 @@ export const DASHBOARD_MENTOR_COMPETENCE_SUMMARY = graphql(`
|
||||||
average_passed
|
average_passed
|
||||||
total_passed
|
total_passed
|
||||||
total_failed
|
total_failed
|
||||||
|
average_evaluation_percent
|
||||||
}
|
}
|
||||||
records {
|
records {
|
||||||
_id
|
_id
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ class AssignmentStatisticsSummaryType(graphene.ObjectType):
|
||||||
average_passed = graphene.Float(required=True)
|
average_passed = graphene.Float(required=True)
|
||||||
total_passed = graphene.Int(required=True)
|
total_passed = graphene.Int(required=True)
|
||||||
total_failed = graphene.Int(required=True)
|
total_failed = graphene.Int(required=True)
|
||||||
|
average_evaluation_percent = graphene.Float()
|
||||||
|
|
||||||
|
|
||||||
class AssignmentsStatisticsType(graphene.ObjectType):
|
class AssignmentsStatisticsType(graphene.ObjectType):
|
||||||
|
|
@ -90,12 +91,17 @@ def create_assignment_summary(
|
||||||
total_passed = sum([m.passed_count for m in completed_metrics])
|
total_passed = sum([m.passed_count for m in completed_metrics])
|
||||||
total_failed = sum([m.failed_count for m in completed_metrics])
|
total_failed = sum([m.failed_count for m in completed_metrics])
|
||||||
|
|
||||||
|
total_average_evaluation_percent = (
|
||||||
|
sum([m.average_evaluation_percent for m in completed_metrics]) / completed_count
|
||||||
|
)
|
||||||
|
|
||||||
return AssignmentStatisticsSummaryType(
|
return AssignmentStatisticsSummaryType(
|
||||||
_id=urql_id, # noqa
|
_id=urql_id, # noqa
|
||||||
completed_count=completed_count, # noqa
|
completed_count=completed_count, # noqa
|
||||||
average_passed=average_passed_completed, # noqa
|
average_passed=average_passed_completed, # noqa
|
||||||
total_passed=total_passed, # noqa
|
total_passed=total_passed, # noqa
|
||||||
total_failed=total_failed, # noqa
|
total_failed=total_failed, # noqa
|
||||||
|
average_evaluation_percent=total_average_evaluation_percent, # noqa
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,8 +201,7 @@ class CourseStatisticsType(BaseStatisticsType):
|
||||||
records, success_total, fail_total = competences(
|
records, success_total, fail_total = competences(
|
||||||
course_slug=str(root.course_slug),
|
course_slug=str(root.course_slug),
|
||||||
course_session_selection_ids=[
|
course_session_selection_ids=[
|
||||||
str(cs)
|
str(cs) for cs in root.course_session_selection_ids # noqa
|
||||||
for cs in root.course_session_selection_ids # noqa
|
|
||||||
],
|
],
|
||||||
user_selection_ids=user_selection_ids, # noqa
|
user_selection_ids=user_selection_ids, # noqa
|
||||||
circle_ids=root.get_circle_ids(info), # noqa
|
circle_ids=root.get_circle_ids(info), # noqa
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue