feat: add statistic filter
This commit is contained in:
parent
d78b216875
commit
c079be32e7
|
|
@ -0,0 +1,101 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from "vue";
|
||||||
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
|
import type { StatisticsCourseSessionPropertiesType } from "@/gql/graphql";
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
_id: string;
|
||||||
|
course_session_id: string;
|
||||||
|
generation: string;
|
||||||
|
circle_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
items: Item[];
|
||||||
|
courseSessionProperties: StatisticsCourseSessionPropertiesType;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const sessionFilter = computed(() => {
|
||||||
|
const f = props.courseSessionProperties.sessions.map((session) => ({
|
||||||
|
name: `Durchführung: ${session.name}`,
|
||||||
|
id: session.id,
|
||||||
|
}));
|
||||||
|
return [{ name: "Durchführung: Alle", id: "_all" }, ...f];
|
||||||
|
});
|
||||||
|
|
||||||
|
const generationFilter = computed(() => {
|
||||||
|
const f = props.courseSessionProperties.generations.map((generation) => ({
|
||||||
|
name: `Generation: ${generation}`,
|
||||||
|
id: generation,
|
||||||
|
}));
|
||||||
|
return [{ name: "Generation: Alle", id: "_all" }, ...f];
|
||||||
|
});
|
||||||
|
|
||||||
|
const circleFilter = computed(() => {
|
||||||
|
const f = props.courseSessionProperties.circles.map((circle) => ({
|
||||||
|
name: `Circle: ${circle.name}`,
|
||||||
|
id: circle.id,
|
||||||
|
}));
|
||||||
|
return [{ name: "Circle: Alle", id: "_all" }, ...f];
|
||||||
|
});
|
||||||
|
|
||||||
|
const sessionFilterValue = ref(sessionFilter.value[0]);
|
||||||
|
const generationFilterValue = ref(generationFilter.value[0]);
|
||||||
|
const circleFilterValue = ref(circleFilter.value[0]);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.courseSessionProperties,
|
||||||
|
() => {
|
||||||
|
sessionFilterValue.value = sessionFilter.value[0];
|
||||||
|
generationFilterValue.value = generationFilter.value[0];
|
||||||
|
circleFilterValue.value = circleFilter.value[0];
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const filteredItems = computed(() => {
|
||||||
|
return props.items.filter((item) => {
|
||||||
|
const sessionMatch =
|
||||||
|
sessionFilterValue.value.id === "_all" ||
|
||||||
|
item.course_session_id === sessionFilterValue.value.id;
|
||||||
|
const generationMatch =
|
||||||
|
generationFilterValue.value.id === "_all" ||
|
||||||
|
item.generation === generationFilterValue.value.id;
|
||||||
|
const circleMatch =
|
||||||
|
circleFilterValue.value.id === "_all" ||
|
||||||
|
item.circle_id === circleFilterValue.value.id;
|
||||||
|
|
||||||
|
return sessionMatch && generationMatch && circleMatch;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-col space-x-2 lg:flex-row">
|
||||||
|
<ItDropdownSelect
|
||||||
|
v-model="sessionFilterValue"
|
||||||
|
class="min-w-[18rem]"
|
||||||
|
:items="sessionFilter"
|
||||||
|
borderless
|
||||||
|
></ItDropdownSelect>
|
||||||
|
<ItDropdownSelect
|
||||||
|
v-model="generationFilterValue"
|
||||||
|
class="min-w-[18rem]"
|
||||||
|
:items="generationFilter"
|
||||||
|
borderless
|
||||||
|
></ItDropdownSelect>
|
||||||
|
<ItDropdownSelect
|
||||||
|
v-model="circleFilterValue"
|
||||||
|
class="min-w-[18rem]"
|
||||||
|
:items="circleFilter"
|
||||||
|
borderless
|
||||||
|
></ItDropdownSelect>
|
||||||
|
</div>
|
||||||
|
<div v-for="item in filteredItems" :key="item._id" class="px-5">
|
||||||
|
<div class="border-t border-gray-500 py-4">
|
||||||
|
<slot :item="item"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -23,7 +23,7 @@ const documents = {
|
||||||
"\n query courseQuery($slug: String!) {\n course(slug: $slug) {\n id\n title\n slug\n category_name\n action_competences {\n competence_id\n ...CoursePageFields\n performance_criteria {\n competence_id\n learning_unit {\n id\n slug\n evaluate_url\n }\n ...CoursePageFields\n }\n }\n learning_path {\n ...CoursePageFields\n topics {\n is_visible\n ...CoursePageFields\n circles {\n description\n goals\n ...CoursePageFields\n learning_sequences {\n icon\n ...CoursePageFields\n learning_units {\n evaluate_url\n ...CoursePageFields\n performance_criteria {\n ...CoursePageFields\n }\n learning_contents {\n can_user_self_toggle_course_completion\n content_url\n minutes\n description\n ...CoursePageFields\n ... on LearningContentAssignmentObjectType {\n assignment_type\n content_assignment {\n id\n }\n competence_certificate {\n ...CoursePageFields\n }\n }\n ... on LearningContentEdoniqTestObjectType {\n checkbox_text\n has_extended_time_test\n content_assignment {\n id\n }\n competence_certificate {\n ...CoursePageFields\n }\n }\n ... on LearningContentRichTextObjectType {\n text\n }\n }\n }\n }\n }\n }\n }\n }\n }\n": types.CourseQueryDocument,
|
"\n query courseQuery($slug: String!) {\n course(slug: $slug) {\n id\n title\n slug\n category_name\n action_competences {\n competence_id\n ...CoursePageFields\n performance_criteria {\n competence_id\n learning_unit {\n id\n slug\n evaluate_url\n }\n ...CoursePageFields\n }\n }\n learning_path {\n ...CoursePageFields\n topics {\n is_visible\n ...CoursePageFields\n circles {\n description\n goals\n ...CoursePageFields\n learning_sequences {\n icon\n ...CoursePageFields\n learning_units {\n evaluate_url\n ...CoursePageFields\n performance_criteria {\n ...CoursePageFields\n }\n learning_contents {\n can_user_self_toggle_course_completion\n content_url\n minutes\n description\n ...CoursePageFields\n ... on LearningContentAssignmentObjectType {\n assignment_type\n content_assignment {\n id\n }\n competence_certificate {\n ...CoursePageFields\n }\n }\n ... on LearningContentEdoniqTestObjectType {\n checkbox_text\n has_extended_time_test\n content_assignment {\n id\n }\n competence_certificate {\n ...CoursePageFields\n }\n }\n ... on LearningContentRichTextObjectType {\n text\n }\n }\n }\n }\n }\n }\n }\n }\n }\n": types.CourseQueryDocument,
|
||||||
"\n query dashboardConfig {\n dashboard_config {\n id\n slug\n name\n dashboard_type\n }\n }\n": types.DashboardConfigDocument,
|
"\n query dashboardConfig {\n dashboard_config {\n id\n slug\n name\n dashboard_type\n }\n }\n": types.DashboardConfigDocument,
|
||||||
"\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 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 session_id\n session_title\n }\n generations\n circles {\n _id\n circle_id\n circle_title\n experts\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 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 circle_id\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 }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n assignment_title\n assignment_type_translation_key\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_passed\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n performances {\n _id\n course_session_id\n generation\n circle_id\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 }\n generations\n circles {\n id\n name\n experts\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 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 circle_id\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 }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n assignment_title\n assignment_type_translation_key\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_passed\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n performances {\n _id\n course_session_id\n generation\n circle_id\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n": types.CourseStatisticsDocument,
|
||||||
"\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\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 $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ export function graphql(source: "\n query dashboardProgress($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 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 session_id\n session_title\n }\n generations\n circles {\n _id\n circle_id\n circle_title\n experts\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 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 circle_id\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 }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n assignment_title\n assignment_type_translation_key\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_passed\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n performances {\n _id\n course_session_id\n generation\n circle_id\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n"): (typeof documents)["\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 session_id\n session_title\n }\n generations\n circles {\n _id\n circle_id\n circle_title\n experts\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 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 circle_id\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 }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n assignment_title\n assignment_type_translation_key\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_passed\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n performances {\n _id\n course_session_id\n generation\n circle_id\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n"];
|
export function graphql(source: "\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 }\n generations\n circles {\n id\n name\n experts\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 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 circle_id\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 }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n assignment_title\n assignment_type_translation_key\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_passed\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n performances {\n _id\n course_session_id\n generation\n circle_id\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n"): (typeof documents)["\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 }\n generations\n circles {\n id\n name\n experts\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 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 circle_id\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 }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n assignment_title\n assignment_type_translation_key\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_passed\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n performances {\n _id\n course_session_id\n generation\n circle_id\n success_count\n fail_count\n details_url\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
|
|
@ -38,21 +38,19 @@ type CourseStatisticsType {
|
||||||
|
|
||||||
type StatisticsCourseSessionPropertiesType {
|
type StatisticsCourseSessionPropertiesType {
|
||||||
_id: ID!
|
_id: ID!
|
||||||
sessions: [StatisticsCourseSessionDataType]!
|
sessions: [StatisticsCourseSessionDataType!]!
|
||||||
generations: [String]!
|
generations: [String!]!
|
||||||
circles: [StatisticsCircleDataType]!
|
circles: [StatisticsCircleDataType!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatisticsCourseSessionDataType {
|
type StatisticsCourseSessionDataType {
|
||||||
_id: ID!
|
id: ID!
|
||||||
session_id: ID!
|
name: String!
|
||||||
session_title: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatisticsCircleDataType {
|
type StatisticsCircleDataType {
|
||||||
_id: ID!
|
id: ID!
|
||||||
circle_id: ID!
|
name: String!
|
||||||
circle_title: String!
|
|
||||||
experts: [String]!
|
experts: [String]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +63,7 @@ type StatisticsCourseSessionsSelectionMetricType {
|
||||||
|
|
||||||
type AttendanceDayPresencesStatisticsType {
|
type AttendanceDayPresencesStatisticsType {
|
||||||
_id: ID!
|
_id: ID!
|
||||||
records: [PresenceRecordStatisticsType]!
|
records: [PresenceRecordStatisticsType!]!
|
||||||
summary: AttendanceSummaryStatisticsType!
|
summary: AttendanceSummaryStatisticsType!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -647,29 +645,24 @@ type LearningContentEdoniqTestObjectType implements CoursePageInterface & Learni
|
||||||
has_extended_time_test: Boolean!
|
has_extended_time_test: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
WORKAROUND:
|
||||||
|
Why is this no DjangoObjectType? It's because we have to "inject"
|
||||||
|
the supervisor into the list of users. This is done in the resolve_users
|
||||||
|
of the CourseSessionObjectType. And there we have to be able to construct
|
||||||
|
a CourseSessionUserObjectsType with the CIRCLES of the supervisor!
|
||||||
|
"""
|
||||||
type CourseSessionUserObjectsType {
|
type CourseSessionUserObjectsType {
|
||||||
id: UUID!
|
id: ID!
|
||||||
role: CourseCourseSessionUserRoleChoices!
|
|
||||||
user_id: UUID!
|
user_id: UUID!
|
||||||
first_name: String!
|
first_name: String!
|
||||||
last_name: String!
|
last_name: String!
|
||||||
email: String!
|
email: String!
|
||||||
avatar_url: String!
|
avatar_url: String!
|
||||||
|
role: String!
|
||||||
circles: [CourseSessionUserExpertCircleType!]!
|
circles: [CourseSessionUserExpertCircleType!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
"""An enumeration."""
|
|
||||||
enum CourseCourseSessionUserRoleChoices {
|
|
||||||
"""Teilnehmer"""
|
|
||||||
MEMBER
|
|
||||||
|
|
||||||
"""Experte/Trainer"""
|
|
||||||
EXPERT
|
|
||||||
|
|
||||||
"""Lernbegleitung"""
|
|
||||||
TUTOR
|
|
||||||
}
|
|
||||||
|
|
||||||
type CourseSessionUserExpertCircleType {
|
type CourseSessionUserExpertCircleType {
|
||||||
id: ID!
|
id: ID!
|
||||||
title: String!
|
title: String!
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ export const CompetencePerformanceStatisticsSummaryType = "CompetencePerformance
|
||||||
export const CompetencePerformanceStatisticsType = "CompetencePerformanceStatisticsType";
|
export const CompetencePerformanceStatisticsType = "CompetencePerformanceStatisticsType";
|
||||||
export const CompetencesStatisticsType = "CompetencesStatisticsType";
|
export const CompetencesStatisticsType = "CompetencesStatisticsType";
|
||||||
export const CoreUserLanguageChoices = "CoreUserLanguageChoices";
|
export const CoreUserLanguageChoices = "CoreUserLanguageChoices";
|
||||||
export const CourseCourseSessionUserRoleChoices = "CourseCourseSessionUserRoleChoices";
|
|
||||||
export const CourseObjectType = "CourseObjectType";
|
export const CourseObjectType = "CourseObjectType";
|
||||||
export const CoursePageInterface = "CoursePageInterface";
|
export const CoursePageInterface = "CoursePageInterface";
|
||||||
export const CourseProgressType = "CourseProgressType";
|
export const CourseProgressType = "CourseProgressType";
|
||||||
|
|
|
||||||
|
|
@ -312,15 +312,13 @@ export const DASHBOARD_COURSE_STATISTICS = graphql(`
|
||||||
course_session_properties {
|
course_session_properties {
|
||||||
_id
|
_id
|
||||||
sessions {
|
sessions {
|
||||||
_id
|
id
|
||||||
session_id
|
name
|
||||||
session_title
|
|
||||||
}
|
}
|
||||||
generations
|
generations
|
||||||
circles {
|
circles {
|
||||||
_id
|
id
|
||||||
circle_id
|
name
|
||||||
circle_title
|
|
||||||
experts
|
experts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,40 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useDashboardStore } from "@/stores/dashboard";
|
import { useDashboardStore } from "@/stores/dashboard";
|
||||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
|
import { computed } from "vue";
|
||||||
|
import type { CourseStatisticsType, PresenceRecordStatisticsType } from "@/gql/graphql";
|
||||||
|
import StatisticFilterList from "@/components/dashboard/StatisticFilterList.vue";
|
||||||
|
import ItProgress from "@/components/ui/ItProgress.vue";
|
||||||
|
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
|
||||||
|
const statistics = computed(() => {
|
||||||
|
return dashboardStore.currentDashBoardData as CourseStatisticsType;
|
||||||
|
});
|
||||||
|
|
||||||
|
const courseSessionName = (courseSessionId: string) => {
|
||||||
|
return statistics.value.course_session_properties.sessions.find(
|
||||||
|
(session) => session.id === courseSessionId
|
||||||
|
)?.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
const circleMeta = (circleId: string) => {
|
||||||
|
return statistics.value.course_session_properties.circles.find(
|
||||||
|
(circle) => circle.id === circleId
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const attendanceStats = (present: number, total: number) => {
|
||||||
|
return {
|
||||||
|
SUCCESS: present,
|
||||||
|
FAIL: total - present,
|
||||||
|
UNKNOWN: 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main>
|
<main v-if="statistics">
|
||||||
<div class="mb-10 flex items-center justify-between">
|
<div class="mb-10 flex items-center justify-between">
|
||||||
<h3>Anwesenheit</h3>
|
<h3>Anwesenheit</h3>
|
||||||
<ItDropdownSelect
|
<ItDropdownSelect
|
||||||
|
|
@ -16,6 +44,43 @@ const dashboardStore = useDashboardStore();
|
||||||
@update:model-value="dashboardStore.switchAndLoadDashboardConfig"
|
@update:model-value="dashboardStore.switchAndLoadDashboardConfig"
|
||||||
></ItDropdownSelect>
|
></ItDropdownSelect>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white">Stats</div>
|
<div v-if="statistics.attendance_day_presences.records" class="mt-8 bg-white">
|
||||||
|
<StatisticFilterList
|
||||||
|
:course-session-properties="statistics.course_session_properties"
|
||||||
|
:items="statistics.attendance_day_presences.records"
|
||||||
|
>
|
||||||
|
<template #default="{ item }">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div>
|
||||||
|
<h4 class="font-bold">
|
||||||
|
Präsenztag: Circle «{{ circleMeta(item.circle_id)?.name }}»
|
||||||
|
</h4>
|
||||||
|
<div>Durchführung «{{ courseSessionName(item.course_session_id) }}»</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
Termin: {{ (item as PresenceRecordStatisticsType).due_date }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
{{ (item as PresenceRecordStatisticsType).participants_present }} von
|
||||||
|
{{ (item as PresenceRecordStatisticsType).participants_total }}
|
||||||
|
Teilnehmenden anwesend
|
||||||
|
</div>
|
||||||
|
<ItProgress
|
||||||
|
:status-count="
|
||||||
|
attendanceStats((item as PresenceRecordStatisticsType).participants_present, (item as PresenceRecordStatisticsType).participants_total)
|
||||||
|
"
|
||||||
|
></ItProgress>
|
||||||
|
<router-link
|
||||||
|
class="underline"
|
||||||
|
:to="(item as PresenceRecordStatisticsType).details_url"
|
||||||
|
>
|
||||||
|
{{ $t("a.Details anschauen") }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</StatisticFilterList>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import type {
|
||||||
AssignmentCompletionStatus as AssignmentCompletionStatusGenerated,
|
AssignmentCompletionStatus as AssignmentCompletionStatusGenerated,
|
||||||
AssignmentObjectType,
|
AssignmentObjectType,
|
||||||
CircleObjectType,
|
CircleObjectType,
|
||||||
CourseCourseSessionUserRoleChoices,
|
|
||||||
CourseSessionObjectType,
|
CourseSessionObjectType,
|
||||||
CourseSessionUserObjectsType,
|
CourseSessionUserObjectsType,
|
||||||
LearningContentAssignmentObjectType,
|
LearningContentAssignmentObjectType,
|
||||||
|
|
@ -435,8 +434,6 @@ export interface CourseSession {
|
||||||
due_dates: DueDate[];
|
due_dates: DueDate[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Role = CourseCourseSessionUserRoleChoices;
|
|
||||||
|
|
||||||
export type CourseSessionUser = CourseSessionUserObjectsType;
|
export type CourseSessionUser = CourseSessionUserObjectsType;
|
||||||
|
|
||||||
export interface ExpertSessionUser extends CourseSessionUser {
|
export interface ExpertSessionUser extends CourseSessionUser {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ class PresenceRecordStatisticsType(graphene.ObjectType):
|
||||||
|
|
||||||
class AttendanceDayPresencesStatisticsType(graphene.ObjectType):
|
class AttendanceDayPresencesStatisticsType(graphene.ObjectType):
|
||||||
_id = graphene.ID(required=True)
|
_id = graphene.ID(required=True)
|
||||||
records = graphene.List(PresenceRecordStatisticsType, required=True)
|
records = graphene.List(
|
||||||
|
graphene.NonNull(PresenceRecordStatisticsType), required=True
|
||||||
|
)
|
||||||
summary = graphene.Field(AttendanceSummaryStatisticsType, required=True)
|
summary = graphene.Field(AttendanceSummaryStatisticsType, required=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,13 @@ from vbv_lernwelt.learnpath.models import Circle
|
||||||
|
|
||||||
|
|
||||||
class StatisticsCourseSessionDataType(graphene.ObjectType):
|
class StatisticsCourseSessionDataType(graphene.ObjectType):
|
||||||
_id = graphene.ID(required=True)
|
id = graphene.ID(required=True)
|
||||||
session_id = graphene.ID(required=True)
|
name = graphene.String(required=True)
|
||||||
session_title = graphene.String(required=True)
|
|
||||||
|
|
||||||
|
|
||||||
class StatisticsCircleDataType(graphene.ObjectType):
|
class StatisticsCircleDataType(graphene.ObjectType):
|
||||||
_id = graphene.ID(required=True)
|
id = graphene.ID(required=True)
|
||||||
circle_id = graphene.ID(required=True)
|
name = graphene.String(required=True)
|
||||||
circle_title = graphene.String(required=True)
|
|
||||||
experts = graphene.List(graphene.String, required=True)
|
experts = graphene.List(graphene.String, required=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -44,9 +42,11 @@ class StatisticsCourseSessionsSelectionMetricType(graphene.ObjectType):
|
||||||
|
|
||||||
class StatisticsCourseSessionPropertiesType(graphene.ObjectType):
|
class StatisticsCourseSessionPropertiesType(graphene.ObjectType):
|
||||||
_id = graphene.ID(required=True)
|
_id = graphene.ID(required=True)
|
||||||
sessions = graphene.List(StatisticsCourseSessionDataType, required=True)
|
sessions = graphene.List(
|
||||||
generations = graphene.List(graphene.String, required=True)
|
graphene.NonNull(StatisticsCourseSessionDataType), required=True
|
||||||
circles = graphene.List(StatisticsCircleDataType, required=True)
|
)
|
||||||
|
generations = graphene.List(graphene.NonNull(graphene.String), required=True)
|
||||||
|
circles = graphene.List(graphene.NonNull(StatisticsCircleDataType), required=True)
|
||||||
|
|
||||||
|
|
||||||
class DashboardType(Enum):
|
class DashboardType(Enum):
|
||||||
|
|
@ -181,9 +181,8 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
for course_session in course_sessions:
|
for course_session in course_sessions:
|
||||||
course_session_data.append(
|
course_session_data.append(
|
||||||
StatisticsCourseSessionDataType(
|
StatisticsCourseSessionDataType(
|
||||||
_id=course_session.id, # noqa
|
id=course_session.id, # noqa
|
||||||
session_id=course_session.id, # noqa
|
name=course_session.title, # noqa
|
||||||
session_title=course_session.title, # noqa
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
generations.add(course_session.generation)
|
generations.add(course_session.generation)
|
||||||
|
|
@ -197,17 +196,17 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
)
|
)
|
||||||
|
|
||||||
for circle in circles:
|
for circle in circles:
|
||||||
circle_data.append(
|
if not any(c.id == circle.id for c in circle_data):
|
||||||
StatisticsCircleDataType(
|
circle_data.append(
|
||||||
_id=circle.id, # noqa
|
StatisticsCircleDataType(
|
||||||
circle_id=circle.id, # noqa
|
id=circle.id, # noqa
|
||||||
circle_title=circle.title, # noqa
|
name=circle.title, # noqa
|
||||||
experts=[ # noqa
|
experts=[ # noqa
|
||||||
f"{su.user.first_name} {su.user.last_name}"
|
f"{su.user.first_name} {su.user.last_name}"
|
||||||
for su in circle.expert.all()
|
for su in circle.expert.all()
|
||||||
],
|
],
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
return StatisticsCourseSessionPropertiesType(
|
return StatisticsCourseSessionPropertiesType(
|
||||||
_id=root._id, # noqa
|
_id=root._id, # noqa
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue