Add mentor components and basic styling
This commit is contained in:
parent
89fc3a8deb
commit
eda9829b36
|
|
@ -1,9 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import type { DashboardConfigType, WidgetType } from "@/services/dashboard";
|
||||
import type { DashboardCourseConfigType, WidgetType } from "@/services/dashboard";
|
||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||
import CompetenceSummary from "@/components/dashboard/CompetenceSummary.vue";
|
||||
import AssignmentSummary from "@/components/dashboard/AssignmentSummary.vue";
|
||||
import MentorOpenTasksCount from "@/components/dashboard/MentorOpenTasksCount.vue";
|
||||
import MentorMenteeCount from "@/components/dashboard/MentorMenteeCount.vue";
|
||||
import MentorCompetenceSummary from "@/components/dashboard/MentorCompetenceSummary.vue";
|
||||
|
||||
const mentorWidgets = [
|
||||
"MentorTasksWidget",
|
||||
|
|
@ -13,7 +16,7 @@ const mentorWidgets = [
|
|||
const progressWidgets = ["CompetenceWidget", "CompetenceCertificateWidget"];
|
||||
|
||||
const props = defineProps<{
|
||||
courseConfig: DashboardConfigType;
|
||||
courseConfig: DashboardCourseConfigType;
|
||||
}>();
|
||||
|
||||
const courseSlug = computed(() => props.courseConfig?.course_slug);
|
||||
|
|
@ -34,9 +37,11 @@ function hasWidget(widget: WidgetType) {
|
|||
|
||||
<template>
|
||||
<div v-if="courseConfig" class="mb-14 space-y-8">
|
||||
<div class="flex flex-col space-y-7 bg-white p-6">
|
||||
<h3>{{ courseName }}</h3>
|
||||
<p>{{ courseConfig.role_key }}</p>
|
||||
<div class="flex flex-col space-y-4 bg-white p-6">
|
||||
<h3 class="mb-4 text-3xl">{{ courseName }}</h3>
|
||||
<p>
|
||||
<span class="rounded bg-gray-300 px-2 py-1">{{ courseConfig.role_key }}</span>
|
||||
</p>
|
||||
<LearningPathDiagram
|
||||
v-if="
|
||||
hasWidget('ProgressWidget') &&
|
||||
|
|
@ -62,10 +67,19 @@ function hasWidget(widget: WidgetType) {
|
|||
:course-id="courseConfig.course_id"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="numberOfMentorWidgets > 0" class="flex flex-col flex-wrap">
|
||||
<div v-if="hasWidget('MentorTasksWidget')">MENTOR_TASKS_WIDGET</div>
|
||||
<div v-if="hasWidget('MentorPersonWidget')">MENTOR_PERSON_WIDGET</div>
|
||||
<div v-if="hasWidget('MentorCompetenceWidget')">MENTOR_COMPETENCE_WIDGET</div>
|
||||
<div v-if="numberOfMentorWidgets > 0" class="flex flex-col flex-wrap md:flex-row">
|
||||
<MentorOpenTasksCount
|
||||
v-if="hasWidget('MentorTasksWidget')"
|
||||
:course-id="courseConfig.course_id"
|
||||
/>
|
||||
<MentorMenteeCount
|
||||
v-if="hasWidget('MentorPersonWidget')"
|
||||
:course-id="courseConfig.course_id"
|
||||
/>
|
||||
<MentorCompetenceSummary
|
||||
v-if="hasWidget('MentorCompetenceWidget')"
|
||||
:course-id="courseConfig.course_id"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref, Ref } from "vue";
|
||||
import { fetchMentorCompetenceSummary } from "@/services/dashboard";
|
||||
import { AssignmentsStatisticsType } from "@/gql/graphql";
|
||||
|
||||
const props = defineProps<{
|
||||
courseId: string;
|
||||
}>();
|
||||
|
||||
const summary: Ref<AssignmentsStatisticsType | null> = ref(null);
|
||||
|
||||
onMounted(async () => {
|
||||
summary.value = await fetchMentorCompetenceSummary(props.courseId);
|
||||
console.log(summary.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="summary" class="w-[325px]">
|
||||
<div class="flex flex-row space-x-3 bg-white">
|
||||
<div
|
||||
class="flex h-[74px] items-center justify-center px-3 py-1 text-3xl font-bold"
|
||||
>
|
||||
<span>{{ summary.summary.total_passed }}</span>
|
||||
</div>
|
||||
<p class="ml-3 mt-0 leading-[74px]">{{ $t("Bestanden") }}</p>
|
||||
</div>
|
||||
<div class="flex flex-row space-x-3 bg-white pb-6">
|
||||
<div
|
||||
class="flex h-[74px] items-center justify-center px-3 py-1 text-3xl font-bold"
|
||||
>
|
||||
<span>{{ summary.summary.total_failed }}</span>
|
||||
</div>
|
||||
<p class="ml-3 mt-0 leading-[74px]">{{ $t("Nicht bestanden") }}</p>
|
||||
</div>
|
||||
<p>{{ $t("Details anschauen") }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref, Ref } from "vue";
|
||||
import { fetchMenteeCount } from "@/services/dashboard";
|
||||
|
||||
const props = defineProps<{
|
||||
courseId: string;
|
||||
}>();
|
||||
|
||||
const menteeCount: Ref<number> = ref(0);
|
||||
|
||||
onMounted(async () => {
|
||||
const data = await fetchMenteeCount(props.courseId);
|
||||
menteeCount.value = data?.mentee_count;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-[325px]">
|
||||
<div class="flex flex-row space-x-3 bg-white pb-6">
|
||||
<div
|
||||
class="flex h-[74px] items-center justify-center px-3 py-1 text-3xl font-bold"
|
||||
>
|
||||
<span>{{ menteeCount }}</span>
|
||||
</div>
|
||||
<p class="ml-3 mt-0 leading-[74px]">{{ $t("Personen, die du begleitest") }}</p>
|
||||
</div>
|
||||
<p>{{ $t("Details anschauen") }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref, Ref } from "vue";
|
||||
import { fetchOpenTasksCount } from "@/services/dashboard";
|
||||
|
||||
const props = defineProps<{
|
||||
courseId: string;
|
||||
}>();
|
||||
|
||||
const openTaskCount: Ref<number> = ref(0);
|
||||
|
||||
onMounted(async () => {
|
||||
const data = await fetchOpenTasksCount(props.courseId);
|
||||
openTaskCount.value = data?.open_task_count;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-[325px]">
|
||||
<div class="flex flex-row space-x-3 bg-white pb-6">
|
||||
<div
|
||||
class="flex h-[74px] w-[74px] items-center justify-center rounded-full border-2 border-green-500 px-3 py-1 text-3xl font-bold"
|
||||
>
|
||||
<span>{{ openTaskCount }}</span>
|
||||
</div>
|
||||
<p class="ml-3 mt-0 leading-[74px]">{{ $t("Elemente zu erledigen") }}</p>
|
||||
</div>
|
||||
<p>{{ $t("Details anschauen") }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -25,6 +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 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 }\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 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 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 }\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 records {\n _id\n course_session_id\n generation\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!) {\n mentor_course_statistics(course_id: $courseId) {\n _id\n assignments {\n _id\n summary {\n _id\n total_passed\n total_failed\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,
|
||||
};
|
||||
|
||||
|
|
@ -90,6 +91,10 @@ export function graphql(source: "\n query dashboardCourseData($courseId: ID!) {
|
|||
* 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 name\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 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 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 }\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 records {\n _id\n course_session_id\n generation\n circle_id\n title\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 }\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 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 }\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 records {\n _id\n course_session_id\n generation\n circle_id\n title\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.
|
||||
*/
|
||||
export function graphql(source: "\n query mentorCourseStatistics($courseId: ID!) {\n mentor_course_statistics(course_id: $courseId) {\n _id\n assignments {\n _id\n summary {\n _id\n total_passed\n total_failed\n }\n }\n }\n }\n"): (typeof documents)["\n query mentorCourseStatistics($courseId: ID!) {\n mentor_course_statistics(course_id: $courseId) {\n _id\n assignments {\n _id\n summary {\n _id\n total_passed\n total_failed\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* 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
|
|
@ -452,3 +452,19 @@ export const DASHBOARD_COURSE_STATISTICS = graphql(`
|
|||
}
|
||||
}
|
||||
`);
|
||||
|
||||
export const DASHBOARD_MENTOR_COMPETENCE_SUMMARY = graphql(`
|
||||
query mentorCourseStatistics($courseId: ID!) {
|
||||
mentor_course_statistics(course_id: $courseId) {
|
||||
_id
|
||||
assignments {
|
||||
_id
|
||||
summary {
|
||||
_id
|
||||
total_passed
|
||||
total_failed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
|
|
|||
|
|
@ -65,10 +65,8 @@ function newDashboardConfigForId(id: string) {
|
|||
@update:model-value="dashboardStore.switchAndLoadDashboardConfig"
|
||||
></ItDropdownSelect>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li v-for="config in dashboardStore.dashboardConfigs" :key="config.id">
|
||||
<p>{{ newDashboardConfigForId(config.id) }}</p>
|
||||
<CoursePanel :course-config="newDashboardConfigForId(config.id)" />
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import { graphqlClient } from "@/graphql/client";
|
||||
import {
|
||||
DASHBOARD_CONFIG,
|
||||
DASHBOARD_COURSE_DATA,
|
||||
DASHBOARD_COURSE_SESSION_PROGRESS,
|
||||
DASHBOARD_COURSE_STATISTICS,
|
||||
DASHBOARD_MENTOR_COMPETENCE_SUMMARY,
|
||||
} from "@/graphql/queries";
|
||||
|
||||
import { itGetCached } from "@/fetchHelpers";
|
||||
import type {
|
||||
AssignmentsStatisticsType,
|
||||
CourseProgressType,
|
||||
CourseStatisticsType,
|
||||
DashboardConfigType,
|
||||
|
|
@ -120,18 +121,18 @@ export const fetchDashboardConfig = async (): Promise<DashboardConfigType[] | nu
|
|||
}
|
||||
};
|
||||
|
||||
export const fetchCourseData = async (
|
||||
export const fetchMentorCompetenceSummary = async (
|
||||
courseId: string
|
||||
): Promise<CourseProgressType | null> => {
|
||||
): Promise<AssignmentsStatisticsType | null> => {
|
||||
try {
|
||||
const res = await graphqlClient.query(DASHBOARD_COURSE_DATA, {
|
||||
const res = await graphqlClient.query(DASHBOARD_MENTOR_COMPETENCE_SUMMARY, {
|
||||
courseId,
|
||||
});
|
||||
|
||||
if (res.error) {
|
||||
console.error("Error fetching data for course ID:", courseId, res.error);
|
||||
}
|
||||
return res.data?.course_progress || null;
|
||||
return res.data?.mentor_course_statistics?.assignments || null;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching data for course ID: ${courseId}`, error);
|
||||
return null;
|
||||
|
|
@ -145,3 +146,15 @@ export async function fetchDashboardPersons() {
|
|||
export async function fetchDashboardConfigv2() {
|
||||
return await itGetCached<DashboardCourseConfigType[]>("/api/dashboard/config/");
|
||||
}
|
||||
|
||||
export async function fetchMenteeCount(courseId: string) {
|
||||
return await itGetCached<{ mentee_count: number }>(
|
||||
`/api/dashboard/course/${courseId}/mentees/`
|
||||
);
|
||||
}
|
||||
|
||||
export async function fetchOpenTasksCount(courseId: string) {
|
||||
return await itGetCached<{ open_task_count: number }>(
|
||||
`/api/dashboard/course/${courseId}/open_tasks/`
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ from django.views import defaults as default_views
|
|||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django_ratelimit.exceptions import Ratelimited
|
||||
from graphene_django.views import GraphQLView
|
||||
from wagtail import urls as wagtail_urls
|
||||
from wagtail.admin import urls as wagtailadmin_urls
|
||||
from wagtail.documents import urls as media_library_urls
|
||||
|
||||
from vbv_lernwelt.api.directory import list_entities
|
||||
from vbv_lernwelt.api.user import get_profile, me_user_view, post_avatar
|
||||
|
|
@ -39,7 +42,8 @@ from vbv_lernwelt.course.views import (
|
|||
request_course_completion_for_user,
|
||||
)
|
||||
from vbv_lernwelt.course_session.views import get_course_session_documents
|
||||
from vbv_lernwelt.dashboard.views import get_dashboard_config, get_dashboard_persons
|
||||
from vbv_lernwelt.dashboard.views import get_dashboard_config, get_dashboard_persons, get_mentee_count, \
|
||||
get_mentor_open_tasks_count
|
||||
from vbv_lernwelt.edoniq_test.views import (
|
||||
export_students,
|
||||
export_students_and_trainers,
|
||||
|
|
@ -58,9 +62,6 @@ from vbv_lernwelt.importer.views import (
|
|||
)
|
||||
from vbv_lernwelt.media_files.views import user_image
|
||||
from vbv_lernwelt.notify.views import email_notification_settings
|
||||
from wagtail import urls as wagtail_urls
|
||||
from wagtail.admin import urls as wagtailadmin_urls
|
||||
from wagtail.documents import urls as media_library_urls
|
||||
|
||||
|
||||
class SignedIntConverter(IntConverter):
|
||||
|
|
@ -120,6 +121,9 @@ urlpatterns = [
|
|||
# dashboard
|
||||
path(r"api/dashboard/persons/", get_dashboard_persons, name="get_dashboard_persons"),
|
||||
path(r"api/dashboard/config/", get_dashboard_config, name="get_dashboard_config"),
|
||||
path(r"api/dashboard/course/<str:course_id>/mentees/", get_mentee_count, name="get_mentee_count"),
|
||||
path(r"api/dashboard/course/<str:course_id>/open_tasks/", get_mentor_open_tasks_count,
|
||||
name="get_mentor_open_tasks_count"),
|
||||
|
||||
# course
|
||||
path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ from rest_framework.decorators import api_view
|
|||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.response import Response
|
||||
|
||||
from vbv_lernwelt.assignment.models import AssignmentCompletion, AssignmentCompletionStatus
|
||||
from vbv_lernwelt.core.models import User
|
||||
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
||||
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser, CourseConfiguration
|
||||
from vbv_lernwelt.course.views import logger
|
||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||
from vbv_lernwelt.self_evaluation_feedback.models import SelfEvaluationFeedback
|
||||
|
||||
|
||||
class WidgetType(Enum):
|
||||
|
|
@ -242,7 +244,7 @@ def get_widgets_for_course(
|
|||
return widgets
|
||||
|
||||
|
||||
def get_role_and_mentor_key(
|
||||
def get_role_key_and_mentor(
|
||||
course_sessions: List[CourseSessionWithRoles], is_uk: bool, is_vv: bool
|
||||
) -> tuple[RoleKeyType, bool]:
|
||||
roles = set()
|
||||
|
|
@ -266,7 +268,7 @@ def get_role_and_mentor_key(
|
|||
return role, is_mentor
|
||||
|
||||
|
||||
def sort_course_sessions_by_course(
|
||||
def collect_course_sessions_by_course(
|
||||
course_sessions: List[CourseSessionWithRoles],
|
||||
) -> dict:
|
||||
course_sessions_by_course = {}
|
||||
|
|
@ -298,11 +300,11 @@ def get_course_config(
|
|||
course_sessions: List[CourseSessionWithRoles],
|
||||
) -> List[CourseConfig]:
|
||||
course_configs = []
|
||||
cs_by_course = sort_course_sessions_by_course(course_sessions)
|
||||
cs_by_course = collect_course_sessions_by_course(course_sessions)
|
||||
for _id, cs_in_course in cs_by_course.items():
|
||||
is_uk = cs_in_course[0].course.configuration.is_uk
|
||||
is_vv = cs_in_course[0].course.configuration.is_vv
|
||||
role_key, is_mentor = get_role_and_mentor_key(cs_in_course, is_uk, is_vv)
|
||||
role_key, is_mentor = get_role_key_and_mentor(cs_in_course, is_uk, is_vv)
|
||||
session_to_continue = get_newest_cs(cs_in_course)
|
||||
course_configs.append(
|
||||
CourseConfig(
|
||||
|
|
@ -339,3 +341,54 @@ def get_dashboard_config(request):
|
|||
except Exception as e:
|
||||
logger.error(e, exc_info=True)
|
||||
return Response({"error": str(e)}, status=404)
|
||||
|
||||
|
||||
@api_view(["GET"])
|
||||
def get_mentee_count(request, course_id: str):
|
||||
try:
|
||||
count = CourseSessionUser.objects.filter(
|
||||
participants__mentor=request.user, course_session__course__id=course_id
|
||||
).count()
|
||||
|
||||
return Response(
|
||||
status=200,
|
||||
data={"mentee_count": count},
|
||||
)
|
||||
except PermissionDenied as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
logger.error(e, exc_info=True)
|
||||
return Response({"error": str(e)}, status=404)
|
||||
|
||||
|
||||
@api_view(["GET"])
|
||||
def get_mentor_open_tasks_count(request, course_id: str):
|
||||
try:
|
||||
open_assigment_count = 0
|
||||
open_feedback_count = 0
|
||||
|
||||
course_configuration = CourseConfiguration.objects.get(course_id=course_id)
|
||||
|
||||
if course_configuration.is_vv:
|
||||
open_assigment_count = AssignmentCompletion.objects.filter(
|
||||
course_session__course__id=course_id,
|
||||
completion_status=AssignmentCompletionStatus.SUBMITTED.value,
|
||||
evaluation_user=request.user, # noqa
|
||||
assignment_user__coursesessionuser__participants__mentor=request.user,
|
||||
).count()
|
||||
|
||||
open_feedback_count = SelfEvaluationFeedback.objects.filter(
|
||||
feedback_provider_user=request.user, # noqa
|
||||
feedback_requester_user__coursesessionuser__participants__mentor=request.user,
|
||||
feedback_submitted=False,
|
||||
).count()
|
||||
|
||||
return Response(
|
||||
status=200,
|
||||
data={"open_task_count": open_assigment_count + open_feedback_count},
|
||||
)
|
||||
except PermissionDenied as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
logger.error(e, exc_info=True)
|
||||
return Response({"error": str(e)}, status=404)
|
||||
|
|
|
|||
Loading…
Reference in New Issue