fix: prepare router / routing
This commit is contained in:
parent
16e0aba504
commit
050d0a6e72
|
|
@ -19,6 +19,7 @@ import {
|
||||||
getCockpitUrl,
|
getCockpitUrl,
|
||||||
getCompetenceNaviUrl,
|
getCompetenceNaviUrl,
|
||||||
getLearningMentorManagementUrl,
|
getLearningMentorManagementUrl,
|
||||||
|
getLearningMentorUrl,
|
||||||
getLearningPathUrl,
|
getLearningPathUrl,
|
||||||
getMediaCenterUrl,
|
getMediaCenterUrl,
|
||||||
} from "@/utils/utils";
|
} from "@/utils/utils";
|
||||||
|
|
@ -109,7 +110,8 @@ const hasNotificationsMenu = computed(() => {
|
||||||
return userStore.loggedIn;
|
return userStore.loggedIn;
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasLearningMentor = computed(() => {
|
// FIXME: Will be removed -> WIP
|
||||||
|
const hasDeprecatedLearningMentor = computed(() => {
|
||||||
if (!inCourse()) {
|
if (!inCourse()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -125,9 +127,21 @@ const hasLearningMentor = computed(() => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Use learning-mentor action instead of deprecated-mentor once we have moved everything from cockpit!
|
|
||||||
return courseSession.actions.includes("deprecated-mentor");
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -262,7 +276,7 @@ const hasLearningMentor = computed(() => {
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<router-link
|
<router-link
|
||||||
v-if="hasLearningMentor"
|
v-if="hasDeprecatedLearningMentor"
|
||||||
data-cy="navigation-learning-mentor-link"
|
data-cy="navigation-learning-mentor-link"
|
||||||
:to="
|
:to="
|
||||||
getLearningMentorManagementUrl(
|
getLearningMentorManagementUrl(
|
||||||
|
|
@ -272,7 +286,20 @@ const hasLearningMentor = computed(() => {
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
:class="{ 'nav-item--active': inLearningMentor() }"
|
: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>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { useRouter } from "vue-router";
|
||||||
import {
|
import {
|
||||||
getCockpitUrl,
|
getCockpitUrl,
|
||||||
getCompetenceNaviUrl,
|
getCompetenceNaviUrl,
|
||||||
|
getLearningMentorUrl,
|
||||||
getLearningPathUrl,
|
getLearningPathUrl,
|
||||||
getMediaCenterUrl,
|
getMediaCenterUrl,
|
||||||
} from "@/utils/utils";
|
} from "@/utils/utils";
|
||||||
|
|
@ -91,6 +92,15 @@ const clickLink = (to: string | undefined) => {
|
||||||
{{ $t("competences.title") }}
|
{{ $t("competences.title") }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</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">
|
<li v-if="hasMediaLibraryMenu" class="mb-6">
|
||||||
<button
|
<button
|
||||||
data-cy="medialibrary-link"
|
data-cy="medialibrary-link"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getCockpitUrl } from "@/utils/utils";
|
import { getLearningMentorUrl } from "@/utils/utils";
|
||||||
import { useDashboardStore } from "@/stores/dashboard";
|
import { useDashboardStore } from "@/stores/dashboard";
|
||||||
|
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
|
@ -13,8 +13,7 @@ const dashboardStore = useDashboardStore();
|
||||||
<div>
|
<div>
|
||||||
<router-link
|
<router-link
|
||||||
class="btn-blue"
|
class="btn-blue"
|
||||||
:to="getCockpitUrl(dashboardStore.currentDashboardConfig.slug)"
|
:to="getLearningMentorUrl(dashboardStore.currentDashboardConfig.slug)"
|
||||||
:data-cy="`continue-course-${dashboardStore.currentDashboardConfig.id}`"
|
|
||||||
>
|
>
|
||||||
{{ $t("a.Zur Lernbegleitung") }}
|
{{ $t("a.Zur Lernbegleitung") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ const route = useRoute();
|
||||||
class="border-t-2 border-t-transparent"
|
class="border-t-2 border-t-transparent"
|
||||||
:class="{
|
:class="{
|
||||||
'border-b-2 border-b-blue-900':
|
'border-b-2 border-b-blue-900':
|
||||||
route.name === 'learningMentorOverview' ||
|
// all detail pages are under overview and prefixed
|
||||||
route.name === 'learningMentor',
|
// except for participants
|
||||||
|
route.name?.toString().startsWith('learningMentor') &&
|
||||||
|
route.name !== 'learningMentorParticipants',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<router-link :to="{ name: 'learningMentorOverview' }" class="block py-3">
|
<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">
|
<router-link :to="{ name: 'learningMentorParticipants' }" class="block py-3">
|
||||||
{{ $t("a.Teilnehmer") }}
|
{{ $t("a.Personen") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ const courseSession = useCurrentCourseSession();
|
||||||
const learningMentees = useLearningMentees(courseSession.value.id);
|
const learningMentees = useLearningMentees(courseSession.value.id);
|
||||||
const summary = learningMentees.summary;
|
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([
|
const statusFilter = ref([
|
||||||
{ name: t("Alle"), id: "_all" },
|
{ 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" });
|
const circleFilterValue = ref({ name: t("a.AlleCircle"), id: "_all" });
|
||||||
|
|
@ -55,42 +55,51 @@ const filteredAssignments: Ref<Assignment[]> = computed(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="summary" class="bg-white">
|
<template v-if="summary">
|
||||||
<div class="flex flex-col space-x-2 lg:flex-row">
|
<h2 class="heading-2 mb-6 mt-6">{{ t("a.Das wurde mit dir geteilt") }}</h2>
|
||||||
<ItDropdownSelect
|
<div class="bg-white">
|
||||||
v-model="statusFilterValue"
|
<div class="flex flex-col lg:flex-row lg:space-x-2">
|
||||||
class="min-w-[10rem]"
|
<ItDropdownSelect
|
||||||
:items="statusFilter"
|
v-model="statusFilterValue"
|
||||||
borderless
|
class="min-w-[10rem]"
|
||||||
></ItDropdownSelect>
|
:items="statusFilter"
|
||||||
<ItDropdownSelect
|
borderless
|
||||||
v-model="circleFilterValue"
|
></ItDropdownSelect>
|
||||||
class="min-w-[18rem]"
|
<ItDropdownSelect
|
||||||
:items="circleFilter"
|
v-model="circleFilterValue"
|
||||||
borderless
|
class="min-w-[18rem]"
|
||||||
></ItDropdownSelect>
|
: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>
|
</div>
|
||||||
<template v-for="item in filteredAssignments" :key="item.id">
|
</template>
|
||||||
<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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="summary" class="bg-white px-4 py-2">
|
<div v-if="summary">
|
||||||
<div
|
<h2 class="heading-2 mb-6 mt-6">{{ $t("a.Personen, die du begleitest") }}</h2>
|
||||||
v-for="participant in summary.participants"
|
<div class="bg-white px-4 py-2">
|
||||||
:key="participant.id"
|
<div
|
||||||
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"
|
v-for="participant in summary.participants"
|
||||||
>
|
:key="participant.id"
|
||||||
<div class="flex items-center space-x-2">
|
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"
|
||||||
<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") }}
|
<div class="flex items-center space-x-2">
|
||||||
</router-link>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export function useRouteLookups() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function inLearningMentor() {
|
function inLearningMentor() {
|
||||||
const regex = new RegExp("/course/[^/]+/mentor($|/)");
|
const regex = new RegExp("/course/[^/]+/learning-mentor($|/)");
|
||||||
return regex.test(route.path);
|
return regex.test(route.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,7 @@ function createCourseUrl(courseSlug: string | undefined, specificSub: string): s
|
||||||
return "/";
|
return "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (["learn", "media", "competence", "cockpit", "mentor"].includes(specificSub)) {
|
return `/course/${courseSlug}/${specificSub}`;
|
||||||
return `/course/${courseSlug}/${specificSub}`;
|
|
||||||
}
|
|
||||||
return `/course/${courseSlug}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCompetenceNaviUrl(courseSlug: string | undefined): string {
|
export function getCompetenceNaviUrl(courseSlug: string | undefined): string {
|
||||||
|
|
@ -32,6 +29,10 @@ export function getLearningPathUrl(courseSlug: string | undefined): string {
|
||||||
return createCourseUrl(courseSlug, "learn");
|
return createCourseUrl(courseSlug, "learn");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLearningMentorUrl(courseSlug: string | undefined): string {
|
||||||
|
return createCourseUrl(courseSlug, "learning-mentor");
|
||||||
|
}
|
||||||
|
|
||||||
export function getCockpitUrl(courseSlug: string | undefined): string {
|
export function getCockpitUrl(courseSlug: string | undefined): string {
|
||||||
return createCourseUrl(courseSlug, "cockpit");
|
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):
|
def has_media_library(user, course_session_id: int):
|
||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
return True
|
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()
|
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:
|
def can_view_profile(user: User, profile_user: CourseSessionUser) -> bool:
|
||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
return True
|
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!
|
# FIXME: Just here WHILE we move cockpit -> learning-mentor THEN remove this!
|
||||||
"deprecated-mentor": is_course_session_member(user, course_session_id),
|
"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),
|
"preview": has_course_session_preview(user, course_session_id),
|
||||||
"media-library": has_media_library(user, course_session_id),
|
"media-library": has_media_library(user, course_session_id),
|
||||||
"appointments": has_appointments(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),
|
"learning-path": is_course_session_member(user, course_session_id),
|
||||||
"competence-navi": 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(
|
"complete-learning-content": can_complete_learning_content(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue