fix: prepare router / routing
This commit is contained in:
parent
16e0aba504
commit
050d0a6e72
|
|
@ -19,6 +19,7 @@ import {
|
|||
getCockpitUrl,
|
||||
getCompetenceNaviUrl,
|
||||
getLearningMentorManagementUrl,
|
||||
getLearningMentorUrl,
|
||||
getLearningPathUrl,
|
||||
getMediaCenterUrl,
|
||||
} from "@/utils/utils";
|
||||
|
|
@ -109,7 +110,8 @@ const hasNotificationsMenu = computed(() => {
|
|||
return userStore.loggedIn;
|
||||
});
|
||||
|
||||
const hasLearningMentor = computed(() => {
|
||||
// FIXME: Will be removed -> WIP
|
||||
const hasDeprecatedLearningMentor = computed(() => {
|
||||
if (!inCourse()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -125,9 +127,21 @@ const hasLearningMentor = computed(() => {
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Use learning-mentor action instead of deprecated-mentor once we have moved everything from cockpit!
|
||||
return courseSession.actions.includes("deprecated-mentor");
|
||||
});
|
||||
|
||||
const hasLearningMentor = computed(() => {
|
||||
if (!inCourse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!courseSessionsStore.currentCourseSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const courseSession = courseSessionsStore.currentCourseSession;
|
||||
return courseSession.actions.includes("learning-mentor");
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -262,7 +276,7 @@ const hasLearningMentor = computed(() => {
|
|||
</router-link>
|
||||
|
||||
<router-link
|
||||
v-if="hasLearningMentor"
|
||||
v-if="hasDeprecatedLearningMentor"
|
||||
data-cy="navigation-learning-mentor-link"
|
||||
:to="
|
||||
getLearningMentorManagementUrl(
|
||||
|
|
@ -272,7 +286,20 @@ const hasLearningMentor = computed(() => {
|
|||
class="nav-item"
|
||||
:class="{ 'nav-item--active': inLearningMentor() }"
|
||||
>
|
||||
{{ t("a.Lernbegleitung") }}
|
||||
{{ t("a.Lernbegleitung") }}🗑️
|
||||
</router-link>
|
||||
<router-link
|
||||
v-if="hasLearningMentor"
|
||||
data-cy="navigation-learning-mentor-link"
|
||||
:to="
|
||||
getLearningMentorUrl(
|
||||
courseSessionsStore.currentCourseSession.course.slug
|
||||
)
|
||||
"
|
||||
class="nav-item"
|
||||
:class="{ 'nav-item--active': inLearningMentor() }"
|
||||
>
|
||||
{{ t("a.Lernbegleitung") }}🆕
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { useRouter } from "vue-router";
|
|||
import {
|
||||
getCockpitUrl,
|
||||
getCompetenceNaviUrl,
|
||||
getLearningMentorUrl,
|
||||
getLearningPathUrl,
|
||||
getMediaCenterUrl,
|
||||
} from "@/utils/utils";
|
||||
|
|
@ -91,6 +92,15 @@ const clickLink = (to: string | undefined) => {
|
|||
{{ $t("competences.title") }}
|
||||
</button>
|
||||
</li>
|
||||
<li v-if="hasLearningMentor" class="mb-6">
|
||||
<button
|
||||
data-cy="navigation-mobile-mentor-link"
|
||||
@click="clickLink(getLearningMentorUrl(courseSession.course.slug))"
|
||||
>
|
||||
{{ $t("a.Lernbegleitung") }}
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li v-if="hasMediaLibraryMenu" class="mb-6">
|
||||
<button
|
||||
data-cy="medialibrary-link"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { getCockpitUrl } from "@/utils/utils";
|
||||
import { getLearningMentorUrl } from "@/utils/utils";
|
||||
import { useDashboardStore } from "@/stores/dashboard";
|
||||
|
||||
const dashboardStore = useDashboardStore();
|
||||
|
|
@ -13,8 +13,7 @@ const dashboardStore = useDashboardStore();
|
|||
<div>
|
||||
<router-link
|
||||
class="btn-blue"
|
||||
:to="getCockpitUrl(dashboardStore.currentDashboardConfig.slug)"
|
||||
:data-cy="`continue-course-${dashboardStore.currentDashboardConfig.id}`"
|
||||
:to="getLearningMentorUrl(dashboardStore.currentDashboardConfig.slug)"
|
||||
>
|
||||
{{ $t("a.Zur Lernbegleitung") }}
|
||||
</router-link>
|
||||
|
|
|
|||
|
|
@ -12,8 +12,10 @@ const route = useRoute();
|
|||
class="border-t-2 border-t-transparent"
|
||||
:class="{
|
||||
'border-b-2 border-b-blue-900':
|
||||
route.name === 'learningMentorOverview' ||
|
||||
route.name === 'learningMentor',
|
||||
// all detail pages are under overview and prefixed
|
||||
// except for participants
|
||||
route.name?.toString().startsWith('learningMentor') &&
|
||||
route.name !== 'learningMentorParticipants',
|
||||
}"
|
||||
>
|
||||
<router-link :to="{ name: 'learningMentorOverview' }" class="block py-3">
|
||||
|
|
@ -27,7 +29,7 @@ const route = useRoute();
|
|||
}"
|
||||
>
|
||||
<router-link :to="{ name: 'learningMentorParticipants' }" class="block py-3">
|
||||
{{ $t("a.Teilnehmer") }}
|
||||
{{ $t("a.Personen") }}
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ const courseSession = useCurrentCourseSession();
|
|||
const learningMentees = useLearningMentees(courseSession.value.id);
|
||||
const summary = learningMentees.summary;
|
||||
|
||||
const statusFilterValue = ref({ name: t("Alle"), id: "_all" });
|
||||
const statusFilterValue = ref({ name: t("a.Zu erledigen"), id: "_todo" });
|
||||
|
||||
const statusFilter = ref([
|
||||
{ name: t("Alle"), id: "_all" },
|
||||
{ name: t("a.Zu erledigen"), id: "todo" },
|
||||
{ name: t("a.Zu erledigen"), id: "_todo" },
|
||||
]);
|
||||
|
||||
const circleFilterValue = ref({ name: t("a.AlleCircle"), id: "_all" });
|
||||
|
|
@ -55,42 +55,51 @@ const filteredAssignments: Ref<Assignment[]> = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="summary" class="bg-white">
|
||||
<div class="flex flex-col space-x-2 lg:flex-row">
|
||||
<ItDropdownSelect
|
||||
v-model="statusFilterValue"
|
||||
class="min-w-[10rem]"
|
||||
:items="statusFilter"
|
||||
borderless
|
||||
></ItDropdownSelect>
|
||||
<ItDropdownSelect
|
||||
v-model="circleFilterValue"
|
||||
class="min-w-[18rem]"
|
||||
:items="circleFilter"
|
||||
borderless
|
||||
></ItDropdownSelect>
|
||||
<template v-if="summary">
|
||||
<h2 class="heading-2 mb-6 mt-6">{{ t("a.Das wurde mit dir geteilt") }}</h2>
|
||||
<div class="bg-white">
|
||||
<div class="flex flex-col lg:flex-row lg:space-x-2">
|
||||
<ItDropdownSelect
|
||||
v-model="statusFilterValue"
|
||||
class="min-w-[10rem]"
|
||||
:items="statusFilter"
|
||||
borderless
|
||||
></ItDropdownSelect>
|
||||
<ItDropdownSelect
|
||||
v-model="circleFilterValue"
|
||||
class="min-w-[18rem]"
|
||||
:items="circleFilter"
|
||||
borderless
|
||||
></ItDropdownSelect>
|
||||
</div>
|
||||
<template v-if="filteredAssignments.length > 0">
|
||||
<template v-for="item in filteredAssignments" :key="item.id">
|
||||
<PraxisAssignmentItem
|
||||
v-if="item.type === 'praxis_assignment'"
|
||||
:circle-title="learningMentees.getCircleTitleById(item.circle_id)"
|
||||
:pending-tasks="item.pending_evaluations"
|
||||
:task-link="{
|
||||
name: 'learningMentorPraxisAssignments',
|
||||
params: { praxisAssignmentId: item.id },
|
||||
}"
|
||||
:task-title="item.title"
|
||||
/>
|
||||
<SelfAssignmentFeedbackAssignmentItem
|
||||
v-else-if="item.type === 'self_evaluation_feedback'"
|
||||
:circle-title="learningMentees.getCircleTitleById(item.circle_id)"
|
||||
:pending-tasks="item.pending_evaluations"
|
||||
:task-link="{
|
||||
name: 'learningMentorSelfEvaluationFeedbackAssignments',
|
||||
params: { learningUnitId: item.id },
|
||||
}"
|
||||
:task-title="item.title"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<div v-else class="m-6 flex flex-row items-center bg-green-200">
|
||||
<it-icon-check class="it-icon"></it-icon-check>
|
||||
<p class="py-4 text-base">{{ $t("a.Du hast alles erledigt.") }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<template v-for="item in filteredAssignments" :key="item.id">
|
||||
<PraxisAssignmentItem
|
||||
v-if="item.type === 'praxis_assignment'"
|
||||
:circle-title="learningMentees.getCircleTitleById(item.circle_id)"
|
||||
:pending-tasks="item.pending_evaluations"
|
||||
:task-link="{
|
||||
name: 'learningMentorPraxisAssignments',
|
||||
params: { praxisAssignmentId: item.id },
|
||||
}"
|
||||
:task-title="item.title"
|
||||
/>
|
||||
<SelfAssignmentFeedbackAssignmentItem
|
||||
v-else-if="item.type === 'self_evaluation_feedback'"
|
||||
:circle-title="learningMentees.getCircleTitleById(item.circle_id)"
|
||||
:pending-tasks="item.pending_evaluations"
|
||||
:task-link="{
|
||||
name: 'learningMentorSelfEvaluationFeedbackAssignments',
|
||||
params: { learningUnitId: item.id },
|
||||
}"
|
||||
:task-title="item.title"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -7,32 +7,35 @@ const { summary } = useLearningMentees(courseSession.value.id);
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="summary" class="bg-white px-4 py-2">
|
||||
<div
|
||||
v-for="participant in summary.participants"
|
||||
:key="participant.id"
|
||||
class="flex flex-col items-start justify-between gap-4 border-b py-2 last:border-b-0 md:flex-row md:items-center md:gap-16"
|
||||
>
|
||||
<div class="flex items-center space-x-2">
|
||||
<img
|
||||
:alt="participant.last_name"
|
||||
class="h-11 w-11 rounded-full"
|
||||
:src="participant.avatar_url || '/static/avatars/myvbv-default-avatar.png'"
|
||||
/>
|
||||
<div>
|
||||
<div class="text-bold">
|
||||
{{ participant.first_name }}
|
||||
{{ participant.last_name }}
|
||||
</div>
|
||||
{{ participant.email }}
|
||||
</div>
|
||||
</div>
|
||||
<router-link
|
||||
:to="{ name: 'userProfile', params: { userId: participant.id } }"
|
||||
class="underline"
|
||||
<div v-if="summary">
|
||||
<h2 class="heading-2 mb-6 mt-6">{{ $t("a.Personen, die du begleitest") }}</h2>
|
||||
<div class="bg-white px-4 py-2">
|
||||
<div
|
||||
v-for="participant in summary.participants"
|
||||
:key="participant.id"
|
||||
class="flex flex-col items-start justify-between gap-4 border-b py-2 last:border-b-0 md:flex-row md:items-center md:gap-16"
|
||||
>
|
||||
{{ $t("cockpit.profileLink") }}
|
||||
</router-link>
|
||||
<div class="flex items-center space-x-2">
|
||||
<img
|
||||
:alt="participant.last_name"
|
||||
class="h-11 w-11 rounded-full"
|
||||
:src="participant.avatar_url || '/static/avatars/myvbv-default-avatar.png'"
|
||||
/>
|
||||
<div>
|
||||
<div class="text-bold">
|
||||
{{ participant.first_name }}
|
||||
{{ participant.last_name }}
|
||||
</div>
|
||||
{{ participant.email }}
|
||||
</div>
|
||||
</div>
|
||||
<router-link
|
||||
:to="{ name: 'userProfile', params: { userId: participant.id } }"
|
||||
class="underline"
|
||||
>
|
||||
{{ $t("cockpit.profileLink") }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export function useRouteLookups() {
|
|||
}
|
||||
|
||||
function inLearningMentor() {
|
||||
const regex = new RegExp("/course/[^/]+/mentor($|/)");
|
||||
const regex = new RegExp("/course/[^/]+/learning-mentor($|/)");
|
||||
return regex.test(route.path);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,7 @@ function createCourseUrl(courseSlug: string | undefined, specificSub: string): s
|
|||
return "/";
|
||||
}
|
||||
|
||||
if (["learn", "media", "competence", "cockpit", "mentor"].includes(specificSub)) {
|
||||
return `/course/${courseSlug}/${specificSub}`;
|
||||
}
|
||||
return `/course/${courseSlug}`;
|
||||
return `/course/${courseSlug}/${specificSub}`;
|
||||
}
|
||||
|
||||
export function getCompetenceNaviUrl(courseSlug: string | undefined): string {
|
||||
|
|
@ -32,6 +29,10 @@ export function getLearningPathUrl(courseSlug: string | undefined): string {
|
|||
return createCourseUrl(courseSlug, "learn");
|
||||
}
|
||||
|
||||
export function getLearningMentorUrl(courseSlug: string | undefined): string {
|
||||
return createCourseUrl(courseSlug, "learning-mentor");
|
||||
}
|
||||
|
||||
export function getCockpitUrl(courseSlug: string | undefined): string {
|
||||
return createCourseUrl(courseSlug, "cockpit");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,13 +51,6 @@ def has_course_session_preview(user, course_session_id: int):
|
|||
)
|
||||
|
||||
|
||||
def has_expert_cockpit(user, course_session_id: int):
|
||||
# FIXME: is_learning_mentor is just here WHILE we move cockpit -> learning-mentor THEN remove this!
|
||||
return is_learning_mentor(user, course_session_id) or is_course_session_expert(
|
||||
user, course_session_id
|
||||
)
|
||||
|
||||
|
||||
def has_media_library(user, course_session_id: int):
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
|
@ -247,6 +240,40 @@ def has_appointments(user: User, course_session_id: int) -> bool:
|
|||
return CourseSessionUser.objects.filter(course_session=course_session_id).exists()
|
||||
|
||||
|
||||
def has_learning_mentor(user: User, course_session_id: int) -> bool:
|
||||
course_session = CourseSession.objects.get(id=course_session_id)
|
||||
|
||||
if course_session is None:
|
||||
return False
|
||||
|
||||
if not course_session.course.configuration.enable_learning_mentor:
|
||||
return False
|
||||
|
||||
if is_learning_mentor(user, course_session_id):
|
||||
return True
|
||||
|
||||
if is_course_session_member(user, course_session_id):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def can_have_learning_mentors(user: User, course_session_id: int) -> bool:
|
||||
if not has_learning_mentor(user, course_session_id):
|
||||
return False
|
||||
|
||||
# limit further, since has_learning_mentor is too broad
|
||||
return is_course_session_member(user, course_session_id)
|
||||
|
||||
|
||||
def can_feedback_mentees(user: User, course_session_id: int) -> bool:
|
||||
if not has_learning_mentor(user, course_session_id):
|
||||
return False
|
||||
|
||||
# limit further, since has_learning_mentor is too broad
|
||||
return is_learning_mentor(user, course_session_id)
|
||||
|
||||
|
||||
def can_view_profile(user: User, profile_user: CourseSessionUser) -> bool:
|
||||
if user.is_superuser:
|
||||
return True
|
||||
|
|
@ -291,11 +318,18 @@ def course_session_permissions(user: User, course_session_id: int) -> list[str]:
|
|||
{
|
||||
# FIXME: Just here WHILE we move cockpit -> learning-mentor THEN remove this!
|
||||
"deprecated-mentor": is_course_session_member(user, course_session_id),
|
||||
"learning-mentor": is_learning_mentor(user, course_session_id),
|
||||
# has learning mentor "tab" access?
|
||||
"learning-mentor": has_learning_mentor(user, course_session_id),
|
||||
"learning-mentor::edit-mentors": can_have_learning_mentors(
|
||||
user, course_session_id
|
||||
),
|
||||
"learning-mentor::feedback-mentees": can_feedback_mentees(
|
||||
user, course_session_id
|
||||
),
|
||||
"preview": has_course_session_preview(user, course_session_id),
|
||||
"media-library": has_media_library(user, course_session_id),
|
||||
"appointments": has_appointments(user, course_session_id),
|
||||
"expert-cockpit": has_expert_cockpit(user, course_session_id),
|
||||
"expert-cockpit": is_course_session_expert(user, course_session_id),
|
||||
"learning-path": is_course_session_member(user, course_session_id),
|
||||
"competence-navi": is_course_session_member(user, course_session_id),
|
||||
"complete-learning-content": can_complete_learning_content(
|
||||
|
|
|
|||
Loading…
Reference in New Issue