WIP: Use REST endpoint
This commit is contained in:
parent
5ba319e524
commit
4a982d8af2
|
|
@ -1,80 +1,71 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref } from "vue";
|
import { computed } from "vue";
|
||||||
import type { CourseProgressType, WidgetType } from "@/gql/graphql";
|
import type { DashboardConfigType, WidgetType } from "@/services/dashboard";
|
||||||
import { DashboardConfigType } from "@/gql/graphql";
|
|
||||||
import { fetchCourseData } from "@/services/dashboard";
|
|
||||||
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
||||||
import CompetenceSummary from "@/components/dashboard/CompetenceSummary.vue";
|
import CompetenceSummary from "@/components/dashboard/CompetenceSummary.vue";
|
||||||
import AssignmentSummary from "@/components/dashboard/AssignmentSummary.vue";
|
import AssignmentSummary from "@/components/dashboard/AssignmentSummary.vue";
|
||||||
|
|
||||||
const mentorWidgets = [
|
const mentorWidgets = [
|
||||||
"MENTOR_TASKS_WIDGET",
|
"MentorTasksWidget",
|
||||||
"MENTOR_PERSON_WIDGET",
|
"MentorPersonWidget",
|
||||||
"MENTOR_COMPETENCE_WIDGET",
|
"MentorCompetenceWidget",
|
||||||
];
|
];
|
||||||
const progressWidgets = ["COMPETENCE_WIDGET", "COMPETENCE_CERTIFICATE_WIDGET"];
|
const progressWidgets = ["CompetenceWidget", "CompetenceCertificateWidget"];
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
courseConfig: DashboardConfigType;
|
courseConfig: DashboardConfigType;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isLoading = ref(true);
|
const courseSlug = computed(() => props.courseConfig?.course_slug);
|
||||||
|
const courseName = computed(() => props.courseConfig?.course_title);
|
||||||
const data = ref<CourseProgressType | null>(null);
|
|
||||||
|
|
||||||
const courseSlug = computed(() => props.courseConfig?.slug);
|
|
||||||
const courseName = computed(() => props.courseConfig?.name);
|
|
||||||
const numberOfMentorWidgets = computed(() => {
|
const numberOfMentorWidgets = computed(() => {
|
||||||
return data.value?.ui_config.widgets.filter((widget) =>
|
return props.courseConfig.widgets.filter((widget) => mentorWidgets.includes(widget))
|
||||||
mentorWidgets.includes(widget)
|
.length;
|
||||||
).length;
|
|
||||||
});
|
});
|
||||||
const numberOfProgressWidgets = computed(() => {
|
const numberOfProgressWidgets = computed(() => {
|
||||||
return data.value?.ui_config.widgets.filter((widget) =>
|
return props.courseConfig.widgets.filter((widget) => progressWidgets.includes(widget))
|
||||||
progressWidgets.includes(widget)
|
.length;
|
||||||
).length;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function hasWidget(widget: WidgetType) {
|
function hasWidget(widget: WidgetType) {
|
||||||
return data.value?.ui_config.widgets.includes(widget);
|
return props.courseConfig.widgets.includes(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
data.value = await fetchCourseData(props.courseConfig.id);
|
|
||||||
isLoading.value = false;
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!isLoading && courseConfig" class="mb-14 space-y-8">
|
<div v-if="courseConfig" class="mb-14 space-y-8">
|
||||||
<div class="flex flex-col space-y-7 bg-white p-6">
|
<div class="flex flex-col space-y-7 bg-white p-6">
|
||||||
<h3>{{ courseName }}</h3>
|
<h3>{{ courseName }}</h3>
|
||||||
<p>{{ data.ui_config.role_key }}</p>
|
<p>{{ courseConfig.role_key }}</p>
|
||||||
<LearningPathDiagram
|
<LearningPathDiagram
|
||||||
v-if="hasWidget('PROGRESS_WIDGET') && data.session_to_continue_id && courseSlug"
|
v-if="
|
||||||
|
hasWidget('ProgressWidget') &&
|
||||||
|
courseConfig.session_to_continue_id &&
|
||||||
|
courseSlug
|
||||||
|
"
|
||||||
:key="courseSlug"
|
:key="courseSlug"
|
||||||
:course-slug="courseSlug"
|
:course-slug="courseSlug"
|
||||||
:course-session-id="data.session_to_continue_id"
|
:course-session-id="courseConfig.session_to_continue_id"
|
||||||
diagram-type="horizontal"
|
diagram-type="horizontal"
|
||||||
></LearningPathDiagram>
|
></LearningPathDiagram>
|
||||||
<div v-if="numberOfProgressWidgets" class="flex flex-col flex-wrap">
|
<div v-if="numberOfProgressWidgets" class="flex flex-col flex-wrap">
|
||||||
<CompetenceSummary
|
<CompetenceSummary
|
||||||
v-if="hasWidget('COMPETENCE_WIDGET')"
|
v-if="hasWidget('CompetenceWidget')"
|
||||||
:course-slug="courseSlug"
|
:course-slug="courseSlug"
|
||||||
:session-to-continue-id="data.session_to_continue_id"
|
:session-to-continue-id="courseConfig.session_to_continue_id"
|
||||||
:course-id="courseConfig.id"
|
:course-id="courseConfig.course_id"
|
||||||
></CompetenceSummary>
|
></CompetenceSummary>
|
||||||
<AssignmentSummary
|
<AssignmentSummary
|
||||||
v-if="hasWidget('COMPETENCE_CERTIFICATE_WIDGET')"
|
v-if="hasWidget('CompetenceCertificateWidget')"
|
||||||
:course-slug="courseSlug"
|
:course-slug="courseSlug"
|
||||||
:session-to-continue-id="data.session_to_continue_id"
|
:session-to-continue-id="courseConfig.session_to_continue_id"
|
||||||
:course-id="courseConfig.id"
|
:course-id="courseConfig.course_id"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="numberOfMentorWidgets > 0" class="flex flex-col flex-wrap">
|
<div v-if="numberOfMentorWidgets > 0" class="flex flex-col flex-wrap">
|
||||||
<div v-if="hasWidget('MENTOR_TASKS_WIDGET')">MENTOR_TASKS_WIDGET</div>
|
<div v-if="hasWidget('MentorTasksWidget')">MENTOR_TASKS_WIDGET</div>
|
||||||
<div v-if="hasWidget('MENTOR_PERSON_WIDGET')">MENTOR_PERSON_WIDGET</div>
|
<div v-if="hasWidget('MentorPersonWidget')">MENTOR_PERSON_WIDGET</div>
|
||||||
<div v-if="hasWidget('MENTOR_COMPETENCE_WIDGET')">MENTOR_COMPETENCE_WIDGET</div>
|
<div v-if="hasWidget('MentorCompetenceWidget')">MENTOR_COMPETENCE_WIDGET</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Component } from "vue";
|
import type { Component, Ref } from "vue";
|
||||||
import { onMounted } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import StatisticPage from "@/pages/dashboard/StatisticPage.vue";
|
import StatisticPage from "@/pages/dashboard/StatisticPage.vue";
|
||||||
import ProgressPage from "@/pages/dashboard/ProgressPage.vue";
|
import ProgressPage from "@/pages/dashboard/ProgressPage.vue";
|
||||||
import SimpleDates from "@/components/dashboard/SimpleDates.vue";
|
import SimpleDates from "@/components/dashboard/SimpleDates.vue";
|
||||||
|
|
@ -13,6 +13,7 @@ import CourseDetailDates from "@/components/dashboard/CourseDetailDates.vue";
|
||||||
import NoCourseSession from "@/components/dashboard/NoCourseSession.vue";
|
import NoCourseSession from "@/components/dashboard/NoCourseSession.vue";
|
||||||
import MentorPage from "@/pages/dashboard/MentorPage.vue";
|
import MentorPage from "@/pages/dashboard/MentorPage.vue";
|
||||||
import CoursePanel from "@/components/dashboard/CoursePanel.vue";
|
import CoursePanel from "@/components/dashboard/CoursePanel.vue";
|
||||||
|
import { DashboardConfigType, fetchDashboardConfigv2 } from "@/services/dashboard";
|
||||||
|
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
|
||||||
|
|
@ -29,7 +30,16 @@ const boards: Record<DashboardType, DashboardPage> = {
|
||||||
PRAXISBILDNER_DASHBOARD: { main: CoursePanel, aside: SimpleDates },
|
PRAXISBILDNER_DASHBOARD: { main: CoursePanel, aside: SimpleDates },
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(dashboardStore.loadDashboardDetails);
|
const dashboardConfigv2: Ref<DashboardConfigType[]> = ref([]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
dashboardConfigv2.value = await fetchDashboardConfigv2();
|
||||||
|
await dashboardStore.loadDashboardDetails();
|
||||||
|
});
|
||||||
|
|
||||||
|
function newDashboardConfigForId(id: string) {
|
||||||
|
return dashboardConfigv2.value.find((config) => config.course_id == +id);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -54,8 +64,8 @@ onMounted(dashboardStore.loadDashboardDetails);
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="config in dashboardStore.dashboardConfigs" :key="config.id">
|
<li v-for="config in dashboardStore.dashboardConfigs" :key="config.id">
|
||||||
<p>{{ config }}</p>
|
<p>{{ newDashboardConfigForId(config.id) }}</p>
|
||||||
<CoursePanel :course-config="config" />
|
<CoursePanel :course-config="newDashboardConfigForId(config.id)" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- keep until we unify the dashboard -->
|
<!-- keep until we unify the dashboard -->
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,21 @@ export type DashboardPersonRoleType =
|
||||||
| "LEARNING_MENTOR"
|
| "LEARNING_MENTOR"
|
||||||
| "LEARNING_MENTEE";
|
| "LEARNING_MENTEE";
|
||||||
|
|
||||||
|
export type DashboardRoleKeyType =
|
||||||
|
| "Supervisor"
|
||||||
|
| "Expert"
|
||||||
|
| "Member"
|
||||||
|
| "MentorUK"
|
||||||
|
| "MentorVV";
|
||||||
|
|
||||||
|
export type WidgetType =
|
||||||
|
| "ProgressWidget"
|
||||||
|
| "CompetenceWidget"
|
||||||
|
| "MentorTasksWidget"
|
||||||
|
| "MentorPersonWidget"
|
||||||
|
| "MentorCompetenceWidget"
|
||||||
|
| "CompetenceCertificateWidget";
|
||||||
|
|
||||||
export type DashboardPersonCourseSessionType = {
|
export type DashboardPersonCourseSessionType = {
|
||||||
id: number;
|
id: number;
|
||||||
session_title: string;
|
session_title: string;
|
||||||
|
|
@ -40,6 +55,19 @@ export type DashboardPersonType = {
|
||||||
course_sessions: DashboardPersonCourseSessionType[];
|
course_sessions: DashboardPersonCourseSessionType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DashboardConfigType = {
|
||||||
|
course_id: string;
|
||||||
|
course_slug: string;
|
||||||
|
course_title: string;
|
||||||
|
role_key: DashboardRoleKeyType;
|
||||||
|
is_uk: boolean;
|
||||||
|
is_vv: boolean;
|
||||||
|
is_mentor: boolean;
|
||||||
|
widgets: WidgetType[];
|
||||||
|
has_preview: boolean;
|
||||||
|
session_to_continue_id: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const fetchStatisticData = async (
|
export const fetchStatisticData = async (
|
||||||
courseId: string
|
courseId: string
|
||||||
): Promise<CourseStatisticsType | null> => {
|
): Promise<CourseStatisticsType | null> => {
|
||||||
|
|
@ -113,3 +141,7 @@ export const fetchCourseData = async (
|
||||||
export async function fetchDashboardPersons() {
|
export async function fetchDashboardPersons() {
|
||||||
return await itGetCached<DashboardPersonType[]>("/api/dashboard/persons/");
|
return await itGetCached<DashboardPersonType[]>("/api/dashboard/persons/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchDashboardConfigv2() {
|
||||||
|
return await itGetCached<DashboardConfigType[]>("/api/dashboard/config/");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ from vbv_lernwelt.course.views import (
|
||||||
request_course_completion_for_user,
|
request_course_completion_for_user,
|
||||||
)
|
)
|
||||||
from vbv_lernwelt.course_session.views import get_course_session_documents
|
from vbv_lernwelt.course_session.views import get_course_session_documents
|
||||||
from vbv_lernwelt.dashboard.views import get_dashboard_persons
|
from vbv_lernwelt.dashboard.views import get_dashboard_config, get_dashboard_persons
|
||||||
from vbv_lernwelt.edoniq_test.views import (
|
from vbv_lernwelt.edoniq_test.views import (
|
||||||
export_students,
|
export_students,
|
||||||
export_students_and_trainers,
|
export_students_and_trainers,
|
||||||
|
|
@ -116,9 +116,10 @@ urlpatterns = [
|
||||||
# notify
|
# notify
|
||||||
re_path(r"api/notify/email_notification_settings/$", email_notification_settings,
|
re_path(r"api/notify/email_notification_settings/$", email_notification_settings,
|
||||||
name='email_notification_settings'),
|
name='email_notification_settings'),
|
||||||
|
|
||||||
# dashboard
|
# dashboard
|
||||||
path(r"api/dashboard/persons/", get_dashboard_persons, name="get_dashboard_persons"),
|
path(r"api/dashboard/persons/", get_dashboard_persons, name="get_dashboard_persons"),
|
||||||
|
path(r"api/dashboard/config/", get_dashboard_config, name="get_dashboard_config"),
|
||||||
|
|
||||||
# course
|
# course
|
||||||
path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"),
|
path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"),
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,9 @@ class DashboardQuery(graphene.ObjectType):
|
||||||
mentees_ids = set()
|
mentees_ids = set()
|
||||||
course_session_ids = set()
|
course_session_ids = set()
|
||||||
|
|
||||||
mentees = CourseSessionUser.objects.filter(participants__mentor=user,
|
mentees = CourseSessionUser.objects.filter(
|
||||||
course_session__course=course).values_list("user", "course_session")
|
participants__mentor=user, course_session__course=course
|
||||||
|
).values_list("user", "course_session")
|
||||||
for user_id, course_session_id in mentees:
|
for user_id, course_session_id in mentees:
|
||||||
mentees_ids.add(user_id)
|
mentees_ids.add(user_id)
|
||||||
course_session_ids.add(course_session_id)
|
course_session_ids.add(course_session_id)
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,9 @@ def create_assignment_summary(course_id, metrics) -> AssignmentStatisticsSummary
|
||||||
|
|
||||||
|
|
||||||
def get_assignment_completion_metrics(
|
def get_assignment_completion_metrics(
|
||||||
course_session: CourseSession, assignment: vbv_lernwelt.assignment.models.Assignment,
|
course_session: CourseSession,
|
||||||
user_selection_ids: List[str] | None
|
assignment: vbv_lernwelt.assignment.models.Assignment,
|
||||||
|
user_selection_ids: List[str] | None,
|
||||||
) -> AssignmentCompletionMetricsType:
|
) -> AssignmentCompletionMetricsType:
|
||||||
course_session_users = CourseSessionUser.objects.filter(
|
course_session_users = CourseSessionUser.objects.filter(
|
||||||
course_session=course_session,
|
course_session=course_session,
|
||||||
|
|
@ -112,7 +113,7 @@ def get_assignment_completion_metrics(
|
||||||
|
|
||||||
def create_record(
|
def create_record(
|
||||||
course_session_assignment: CourseSessionAssignment | CourseSessionEdoniqTest,
|
course_session_assignment: CourseSessionAssignment | CourseSessionEdoniqTest,
|
||||||
user_selection_ids: List[str] | None
|
user_selection_ids: List[str] | None,
|
||||||
) -> AssignmentStatisticsRecordType:
|
) -> AssignmentStatisticsRecordType:
|
||||||
if isinstance(course_session_assignment, CourseSessionAssignment):
|
if isinstance(course_session_assignment, CourseSessionAssignment):
|
||||||
due_date = course_session_assignment.submission_deadline
|
due_date = course_session_assignment.submission_deadline
|
||||||
|
|
@ -160,14 +161,18 @@ def assignments(
|
||||||
],
|
],
|
||||||
learning_content__content_assignment__competence_certificate__isnull=False,
|
learning_content__content_assignment__competence_certificate__isnull=False,
|
||||||
):
|
):
|
||||||
record = create_record(course_session_assignment=csa, user_selection_ids=user_selection_ids)
|
record = create_record(
|
||||||
|
course_session_assignment=csa, user_selection_ids=user_selection_ids
|
||||||
|
)
|
||||||
records.append(record)
|
records.append(record)
|
||||||
|
|
||||||
for cset in CourseSessionEdoniqTest.objects.filter(
|
for cset in CourseSessionEdoniqTest.objects.filter(
|
||||||
course_session=course_session,
|
course_session=course_session,
|
||||||
learning_content__content_assignment__competence_certificate__isnull=False,
|
learning_content__content_assignment__competence_certificate__isnull=False,
|
||||||
):
|
):
|
||||||
record = create_record(course_session_assignment=cset, user_selection_ids=user_selection_ids)
|
record = create_record(
|
||||||
|
course_session_assignment=cset, user_selection_ids=user_selection_ids
|
||||||
|
)
|
||||||
records.append(record)
|
records.append(record)
|
||||||
|
|
||||||
return AssignmentsStatisticsType(
|
return AssignmentsStatisticsType(
|
||||||
|
|
|
||||||
|
|
@ -241,8 +241,11 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
)
|
)
|
||||||
|
|
||||||
def resolve_competences(root, info) -> CompetencesStatisticsType:
|
def resolve_competences(root, info) -> CompetencesStatisticsType:
|
||||||
user_selection_ids = [str(user) for user in
|
user_selection_ids = (
|
||||||
root.user_selection_ids] if root.user_selection_ids else None # noqa
|
[str(user) for user in root.user_selection_ids]
|
||||||
|
if root.user_selection_ids
|
||||||
|
else None
|
||||||
|
) # noqa
|
||||||
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=[
|
||||||
|
|
@ -261,8 +264,11 @@ class CourseStatisticsType(graphene.ObjectType):
|
||||||
)
|
)
|
||||||
|
|
||||||
def resolve_assignments(root, info) -> AssignmentsStatisticsType:
|
def resolve_assignments(root, info) -> AssignmentsStatisticsType:
|
||||||
user_selection_ids = [str(user) for user in
|
user_selection_ids = (
|
||||||
root.user_selection_ids] if root.user_selection_ids else None # noqa
|
[str(user) for user in root.user_selection_ids]
|
||||||
|
if root.user_selection_ids
|
||||||
|
else None
|
||||||
|
) # noqa
|
||||||
return assignments(
|
return assignments(
|
||||||
course_id=root.course_id,
|
course_id=root.course_id,
|
||||||
course_session_selection_ids=root.course_session_selection_ids,
|
course_session_selection_ids=root.course_session_selection_ids,
|
||||||
|
|
@ -381,7 +387,11 @@ def get_ui_config_for_course(course: Course, user: User) -> UIConfigType:
|
||||||
# mentors
|
# mentors
|
||||||
if course.id in mentor_course_ids:
|
if course.id in mentor_course_ids:
|
||||||
if not role_key:
|
if not role_key:
|
||||||
role_key = RoleKeyType.MENTOR_UK if course.id in UK_COURSE_IDS else RoleKeyType.MENTOR_VV
|
role_key = (
|
||||||
|
RoleKeyType.MENTOR_UK
|
||||||
|
if course.id in UK_COURSE_IDS
|
||||||
|
else RoleKeyType.MENTOR_VV
|
||||||
|
)
|
||||||
has_preview = True
|
has_preview = True
|
||||||
widgets.append(WidgetType.MENTOR_TASKS_WIDGET)
|
widgets.append(WidgetType.MENTOR_TASKS_WIDGET)
|
||||||
widgets.append(WidgetType.MENTOR_PERSON_WIDGET)
|
widgets.append(WidgetType.MENTOR_PERSON_WIDGET)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from dataclasses import dataclass
|
from dataclasses import asdict, dataclass
|
||||||
from typing import List, Set
|
from typing import List, Set
|
||||||
|
|
||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
|
|
@ -9,6 +9,7 @@ from vbv_lernwelt.core.models import User
|
||||||
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
|
||||||
from vbv_lernwelt.course.views import logger
|
from vbv_lernwelt.course.views import logger
|
||||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||||
|
from vbv_lernwelt.dashboard.graphql.types.dashboard import RoleKeyType, WidgetType
|
||||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,6 +26,20 @@ class CourseSessionWithRoles:
|
||||||
raise NotImplementedError("This proxy object cannot be saved.")
|
raise NotImplementedError("This proxy object cannot be saved.")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class CourseConfig:
|
||||||
|
course_id: int
|
||||||
|
course_slug: str
|
||||||
|
course_title: str
|
||||||
|
role_key: str
|
||||||
|
is_uk: bool
|
||||||
|
is_vv: bool
|
||||||
|
is_mentor: bool
|
||||||
|
widgets: List[str]
|
||||||
|
has_preview: bool
|
||||||
|
session_to_continue_id: str | None
|
||||||
|
|
||||||
|
|
||||||
def get_course_sessions_with_roles_for_user(user: User) -> List[CourseSessionWithRoles]:
|
def get_course_sessions_with_roles_for_user(user: User) -> List[CourseSessionWithRoles]:
|
||||||
result_course_sessions = {}
|
result_course_sessions = {}
|
||||||
|
|
||||||
|
|
@ -67,6 +82,18 @@ def get_course_sessions_with_roles_for_user(user: User) -> List[CourseSessionWit
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def has_cs_role(roles: Set[str]) -> bool:
|
||||||
|
return bool(roles & {"SUPERVISOR", "EXPERT", "MEMBER"})
|
||||||
|
|
||||||
|
|
||||||
|
def user_role(roles: Set[str]) -> str:
|
||||||
|
return (
|
||||||
|
"SUPERVISOR"
|
||||||
|
if "SUPERVISOR" in roles
|
||||||
|
else ("EXPERT" if "EXPERT" in roles else "MEMBER")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@api_view(["GET"])
|
@api_view(["GET"])
|
||||||
def get_dashboard_persons(request):
|
def get_dashboard_persons(request):
|
||||||
try:
|
try:
|
||||||
|
|
@ -74,19 +101,11 @@ def get_dashboard_persons(request):
|
||||||
|
|
||||||
result_persons = {}
|
result_persons = {}
|
||||||
for cs in course_sessions:
|
for cs in course_sessions:
|
||||||
if {
|
if has_cs_role(cs.roles) and cs.course.configuration.is_uk:
|
||||||
"SUPERVISOR",
|
|
||||||
"EXPERT",
|
|
||||||
"MEMBER",
|
|
||||||
} & cs.roles and cs.course.configuration.is_uk:
|
|
||||||
course_session_users = CourseSessionUser.objects.filter(
|
course_session_users = CourseSessionUser.objects.filter(
|
||||||
course_session=cs.id
|
course_session=cs.id
|
||||||
)
|
)
|
||||||
my_role = (
|
my_role = user_role(cs.roles)
|
||||||
"SUPERVISOR"
|
|
||||||
if "SUPERVISOR" in cs.roles
|
|
||||||
else ("EXPERT" if "EXPERT" in cs.roles else "MEMBER")
|
|
||||||
)
|
|
||||||
for csu in course_session_users:
|
for csu in course_session_users:
|
||||||
result_persons[csu.user.id] = {
|
result_persons[csu.user.id] = {
|
||||||
"user_id": csu.user.id,
|
"user_id": csu.user.id,
|
||||||
|
|
@ -183,3 +202,123 @@ def get_dashboard_persons(request):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(e, exc_info=True)
|
logger.error(e, exc_info=True)
|
||||||
return Response({"error": str(e)}, status=404)
|
return Response({"error": str(e)}, status=404)
|
||||||
|
|
||||||
|
|
||||||
|
def get_widgets_for_course(
|
||||||
|
role_key: RoleKeyType, is_uk: bool, is_vv: bool, is_mentor: bool
|
||||||
|
) -> List[str]:
|
||||||
|
widgets = []
|
||||||
|
|
||||||
|
if role_key == RoleKeyType.MEMBER:
|
||||||
|
widgets.append(WidgetType.PROGRESS_WIDGET.value)
|
||||||
|
widgets.append(WidgetType.COMPETENCE_WIDGET.value)
|
||||||
|
if is_uk:
|
||||||
|
widgets.append(WidgetType.COMPETENCE_CERTIFICATE_WIDGET.value)
|
||||||
|
|
||||||
|
if is_mentor:
|
||||||
|
widgets.append(WidgetType.MENTOR_PERSON_WIDGET.value)
|
||||||
|
if is_vv:
|
||||||
|
widgets.append(WidgetType.MENTOR_TASKS_WIDGET.value)
|
||||||
|
if is_uk:
|
||||||
|
widgets.append(WidgetType.MENTOR_COMPETENCE_WIDGET.value)
|
||||||
|
|
||||||
|
return widgets
|
||||||
|
|
||||||
|
|
||||||
|
def get_role_and_mentor_key(
|
||||||
|
course_sessions: List[CourseSessionWithRoles], is_uk: bool, is_vv: bool
|
||||||
|
) -> tuple[RoleKeyType, bool]:
|
||||||
|
roles = set()
|
||||||
|
role = None
|
||||||
|
for cs in course_sessions:
|
||||||
|
roles.update(cs.roles)
|
||||||
|
|
||||||
|
if "SUPERVISOR" in roles:
|
||||||
|
role = RoleKeyType.SUPERVISOR
|
||||||
|
elif "EXPERT" in roles:
|
||||||
|
role = RoleKeyType.TRAINER
|
||||||
|
elif "MEMBER" in roles:
|
||||||
|
role = RoleKeyType.MEMBER
|
||||||
|
elif "LEARNING_MENTOR" in roles:
|
||||||
|
if is_uk:
|
||||||
|
role = RoleKeyType.MENTOR_UK
|
||||||
|
elif is_vv:
|
||||||
|
role = RoleKeyType.MENTOR_VV
|
||||||
|
|
||||||
|
is_mentor = "LEARNING_MENTOR" in roles
|
||||||
|
return role, is_mentor
|
||||||
|
|
||||||
|
|
||||||
|
def sort_course_sessions_by_course(
|
||||||
|
course_sessions: List[CourseSessionWithRoles],
|
||||||
|
) -> dict:
|
||||||
|
course_sessions_by_course = {}
|
||||||
|
for cs in course_sessions:
|
||||||
|
if cs.course.id not in course_sessions_by_course:
|
||||||
|
course_sessions_by_course[cs.course.id] = []
|
||||||
|
course_sessions_by_course[cs.course.id].append(cs)
|
||||||
|
return course_sessions_by_course
|
||||||
|
|
||||||
|
|
||||||
|
def has_preview(role_key: RoleKeyType) -> bool:
|
||||||
|
return role_key in [RoleKeyType.MENTOR_UK, RoleKeyType.MENTOR_VV]
|
||||||
|
|
||||||
|
|
||||||
|
def get_newest_cs(
|
||||||
|
course_sessions: List[CourseSessionWithRoles],
|
||||||
|
) -> CourseSessionWithRoles | None:
|
||||||
|
newest: CourseSessionWithRoles | None = None
|
||||||
|
|
||||||
|
for cs in course_sessions:
|
||||||
|
generation_newest = newest.generation if newest else None
|
||||||
|
if generation_newest is None or cs.generation > generation_newest:
|
||||||
|
newest = cs
|
||||||
|
|
||||||
|
return newest
|
||||||
|
|
||||||
|
|
||||||
|
def get_course_config(
|
||||||
|
course_sessions: List[CourseSessionWithRoles],
|
||||||
|
) -> List[CourseConfig]:
|
||||||
|
course_configs = []
|
||||||
|
cs_by_course = sort_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)
|
||||||
|
session_to_continue = get_newest_cs(cs_in_course)
|
||||||
|
course_configs.append(
|
||||||
|
CourseConfig(
|
||||||
|
course_id=cs_in_course[0].course.id,
|
||||||
|
course_slug=cs_in_course[0].course.slug,
|
||||||
|
course_title=cs_in_course[0].course.title,
|
||||||
|
role_key=role_key.value,
|
||||||
|
is_uk=is_uk,
|
||||||
|
is_vv=is_vv,
|
||||||
|
is_mentor=is_mentor,
|
||||||
|
widgets=get_widgets_for_course(role_key, is_uk, is_vv, is_mentor),
|
||||||
|
has_preview=has_preview(role_key),
|
||||||
|
session_to_continue_id=str(session_to_continue.id)
|
||||||
|
if session_to_continue
|
||||||
|
else None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return course_configs
|
||||||
|
|
||||||
|
|
||||||
|
@api_view(["GET"])
|
||||||
|
def get_dashboard_config(request):
|
||||||
|
try:
|
||||||
|
course_sessions = get_course_sessions_with_roles_for_user(request.user) # noqa
|
||||||
|
course_configs = get_course_config(course_sessions)
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
status=200,
|
||||||
|
data=[asdict(cc) for cc in course_configs],
|
||||||
|
)
|
||||||
|
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