Merged in feature/VBV-297-trainer-landet-direkt-in-cockpit (pull request #99)
Trainer landet direkt in cockpit Approved-by: Daniel Egger
This commit is contained in:
commit
c75c9d0b40
|
|
@ -16,10 +16,6 @@ echo "$BRANCH_NAME_SLUG"
|
||||||
DEFAULT_APP_NAME="vbv-$BRANCH_NAME_SLUG"
|
DEFAULT_APP_NAME="vbv-$BRANCH_NAME_SLUG"
|
||||||
APP_NAME=${1:-$DEFAULT_APP_NAME}
|
APP_NAME=${1:-$DEFAULT_APP_NAME}
|
||||||
|
|
||||||
# remove multiple dashes and make sure it does not end with a dash
|
|
||||||
APP_NAME=$(echo "$APP_NAME" | sed -E 's/-+/-/g')
|
|
||||||
APP_NAME=$(echo "$APP_NAME" | sed 's/-\+$//')
|
|
||||||
|
|
||||||
# shorten APP_NAME to 32 characters
|
# shorten APP_NAME to 32 characters
|
||||||
# app names with more character seem to fail in some steps in CapRover
|
# app names with more character seem to fail in some steps in CapRover
|
||||||
# CapRover generates longer names out from the app name and there
|
# CapRover generates longer names out from the app name and there
|
||||||
|
|
@ -29,6 +25,10 @@ if (( ${#APP_NAME} > 32 )); then
|
||||||
APP_NAME=$(echo -n "${APP_NAME:0:28}-${hash}")
|
APP_NAME=$(echo -n "${APP_NAME:0:28}-${hash}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# remove multiple dashes and make sure it does not end with a dash
|
||||||
|
APP_NAME=$(echo "$APP_NAME" | sed -E 's/-+/-/g')
|
||||||
|
APP_NAME=$(echo "$APP_NAME" | sed 's/-\+$//')
|
||||||
|
|
||||||
echo "Deploy to $APP_NAME"
|
echo "Deploy to $APP_NAME"
|
||||||
|
|
||||||
VITE_GRAPHQL_URL="/server/graphql/"
|
VITE_GRAPHQL_URL="/server/graphql/"
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ onMounted(() => {
|
||||||
v-if="
|
v-if="
|
||||||
inCourse() &&
|
inCourse() &&
|
||||||
courseSessionsStore.currentCourseSession &&
|
courseSessionsStore.currentCourseSession &&
|
||||||
courseSessionsStore.hasCockpit
|
courseSessionsStore.currentCourseSessionHasCockpit
|
||||||
"
|
"
|
||||||
:to="`${courseSessionsStore.currentCourseSession.course_url}/cockpit`"
|
:to="`${courseSessionsStore.currentCourseSession.course_url}/cockpit`"
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
import LearningPathDiagramSmall from "@/components/learningPath/LearningPathDiagramSmall.vue";
|
import LearningPathDiagramSmall from "@/components/learningPath/LearningPathDiagramSmall.vue";
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
|
import type { CourseSession } from "@/types";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import { onMounted } from "vue";
|
import { computed, onMounted } from "vue";
|
||||||
|
|
||||||
log.debug("DashboardPage created");
|
log.debug("DashboardPage created");
|
||||||
|
|
||||||
|
|
@ -13,6 +14,15 @@ const courseSessionsStore = useCourseSessionsStore();
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
log.debug("DashboardPage mounted");
|
log.debug("DashboardPage mounted");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getNextStepLink = (courseSession: CourseSession) => {
|
||||||
|
return computed(() => {
|
||||||
|
if (courseSessionsStore.hasCockpit(courseSession)) {
|
||||||
|
return courseSession.cockpit_url;
|
||||||
|
}
|
||||||
|
return courseSession.learning_path_url;
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -44,7 +54,7 @@ onMounted(async () => {
|
||||||
<div>
|
<div>
|
||||||
<router-link
|
<router-link
|
||||||
class="btn-blue"
|
class="btn-blue"
|
||||||
:to="courseSession.learning_path_url"
|
:to="getNextStepLink(courseSession).value"
|
||||||
:data-cy="`continue-course-${courseSession.course.id}`"
|
:data-cy="`continue-course-${courseSession.course.id}`"
|
||||||
>
|
>
|
||||||
{{ $t("general.nextStep") }}
|
{{ $t("general.nextStep") }}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ describe("Guards", () => {
|
||||||
|
|
||||||
it("cannot route to cockpit", () => {
|
it("cannot route to cockpit", () => {
|
||||||
vi.spyOn(courseSessions, "useCourseSessionsStore").mockReturnValue({
|
vi.spyOn(courseSessions, "useCourseSessionsStore").mockReturnValue({
|
||||||
hasCockpit: false,
|
currentCourseSessionHasCockpit: false,
|
||||||
});
|
});
|
||||||
const slug = "test";
|
const slug = "test";
|
||||||
expect(expertRequired({ params: { courseSlug: "test" } })).toEqual(
|
expect(expertRequired({ params: { courseSlug: "test" } })).toEqual(
|
||||||
|
|
@ -27,7 +27,7 @@ describe("Guards", () => {
|
||||||
|
|
||||||
it("can route to cockpit", () => {
|
it("can route to cockpit", () => {
|
||||||
vi.spyOn(courseSessions, "useCourseSessionsStore").mockReturnValue({
|
vi.spyOn(courseSessions, "useCourseSessionsStore").mockReturnValue({
|
||||||
hasCockpit: true,
|
currentCourseSessionHasCockpit: true,
|
||||||
});
|
});
|
||||||
const to = {
|
const to = {
|
||||||
params: {
|
params: {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const loginRequired = (to: RouteLocationNormalized) => {
|
||||||
|
|
||||||
export const expertRequired: NavigationGuard = (to: RouteLocationNormalized) => {
|
export const expertRequired: NavigationGuard = (to: RouteLocationNormalized) => {
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
const courseSessionsStore = useCourseSessionsStore();
|
||||||
if (courseSessionsStore.hasCockpit) {
|
if (courseSessionsStore.currentCourseSessionHasCockpit) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
const courseSlug = to.params.courseSlug as string;
|
const courseSlug = to.params.courseSlug as string;
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ describe("CourseSession Store", () => {
|
||||||
courseSessionsStore._currentCourseSlug = "test-course";
|
courseSessionsStore._currentCourseSlug = "test-course";
|
||||||
courseSessionsStore.allCourseSessions = courseSessions;
|
courseSessionsStore.allCourseSessions = courseSessions;
|
||||||
|
|
||||||
expect(courseSessionsStore.hasCockpit).toBeFalsy();
|
expect(courseSessionsStore.currentCourseSessionHasCockpit).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("superuser has cockpit", () => {
|
it("superuser has cockpit", () => {
|
||||||
|
|
@ -77,7 +77,7 @@ describe("CourseSession Store", () => {
|
||||||
courseSessionsStore._currentCourseSlug = "test-course";
|
courseSessionsStore._currentCourseSlug = "test-course";
|
||||||
courseSessionsStore.allCourseSessions = courseSessions;
|
courseSessionsStore.allCourseSessions = courseSessions;
|
||||||
|
|
||||||
expect(courseSessionsStore.hasCockpit).toBeTruthy();
|
expect(courseSessionsStore.currentCourseSessionHasCockpit).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("expert has cockpit", () => {
|
it("expert has cockpit", () => {
|
||||||
|
|
@ -90,6 +90,6 @@ describe("CourseSession Store", () => {
|
||||||
courseSessionsStore._currentCourseSlug = "test-course";
|
courseSessionsStore._currentCourseSlug = "test-course";
|
||||||
courseSessionsStore.allCourseSessions = courseSessions;
|
courseSessionsStore.allCourseSessions = courseSessions;
|
||||||
|
|
||||||
expect(courseSessionsStore.hasCockpit).toBeTruthy();
|
expect(courseSessionsStore.currentCourseSessionHasCockpit).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -124,13 +124,9 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
return allCourseSessionsForCourse(_currentCourseSlug.value);
|
return allCourseSessionsForCourse(_currentCourseSlug.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasCockpit = computed(() => {
|
const currentCourseSessionHasCockpit = computed(() => {
|
||||||
if (currentCourseSession.value) {
|
if (currentCourseSession.value) {
|
||||||
const userStore = useUserStore();
|
return hasCockpit(currentCourseSession.value);
|
||||||
return (
|
|
||||||
userStore.course_session_experts.includes(currentCourseSession.value.id) ||
|
|
||||||
userStore.is_superuser
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -182,6 +178,14 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function hasCockpit(couseSession: CourseSession) {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
return (
|
||||||
|
userStore.course_session_experts.includes(couseSession.id) ||
|
||||||
|
userStore.is_superuser
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function addDocument(document: CircleDocument) {
|
function addDocument(document: CircleDocument) {
|
||||||
currentCourseSession.value?.documents.push(document);
|
currentCourseSession.value?.documents.push(document);
|
||||||
}
|
}
|
||||||
|
|
@ -232,6 +236,7 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
courseSessionForCourse,
|
courseSessionForCourse,
|
||||||
switchCourseSession,
|
switchCourseSession,
|
||||||
hasCockpit,
|
hasCockpit,
|
||||||
|
currentCourseSessionHasCockpit,
|
||||||
canUploadCircleDocuments,
|
canUploadCircleDocuments,
|
||||||
circleDocuments,
|
circleDocuments,
|
||||||
circleExperts,
|
circleExperts,
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,7 @@ export interface CourseSession {
|
||||||
start_date: string;
|
start_date: string;
|
||||||
end_date: string;
|
end_date: string;
|
||||||
learning_path_url: string;
|
learning_path_url: string;
|
||||||
|
cockpit_url: string;
|
||||||
competence_url: string;
|
competence_url: string;
|
||||||
course_url: string;
|
course_url: string;
|
||||||
media_library_url: string;
|
media_library_url: string;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ class Course(models.Model):
|
||||||
def get_learning_path_url(self):
|
def get_learning_path_url(self):
|
||||||
return self.get_learning_path().get_frontend_url()
|
return self.get_learning_path().get_frontend_url()
|
||||||
|
|
||||||
|
def get_cockpit_url(self):
|
||||||
|
return self.get_learning_path().get_cockpit_url()
|
||||||
|
|
||||||
def get_competence_url(self):
|
def get_competence_url(self):
|
||||||
from vbv_lernwelt.competence.models import CompetenceProfilePage
|
from vbv_lernwelt.competence.models import CompetenceProfilePage
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
course = serializers.SerializerMethodField()
|
course = serializers.SerializerMethodField()
|
||||||
course_url = serializers.SerializerMethodField()
|
course_url = serializers.SerializerMethodField()
|
||||||
learning_path_url = serializers.SerializerMethodField()
|
learning_path_url = serializers.SerializerMethodField()
|
||||||
|
cockpit_url = serializers.SerializerMethodField()
|
||||||
competence_url = serializers.SerializerMethodField()
|
competence_url = serializers.SerializerMethodField()
|
||||||
media_library_url = serializers.SerializerMethodField()
|
media_library_url = serializers.SerializerMethodField()
|
||||||
documents = serializers.SerializerMethodField()
|
documents = serializers.SerializerMethodField()
|
||||||
|
|
@ -59,6 +60,9 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
def get_learning_path_url(self, obj):
|
def get_learning_path_url(self, obj):
|
||||||
return obj.course.get_learning_path_url()
|
return obj.course.get_learning_path_url()
|
||||||
|
|
||||||
|
def get_cockpit_url(self, obj):
|
||||||
|
return obj.course.get_cockpit_url()
|
||||||
|
|
||||||
def get_media_library_url(self, obj):
|
def get_media_library_url(self, obj):
|
||||||
return obj.course.get_media_library_url()
|
return obj.course.get_media_library_url()
|
||||||
|
|
||||||
|
|
@ -85,6 +89,7 @@ class CourseSessionSerializer(serializers.ModelSerializer):
|
||||||
"attendance_courses",
|
"attendance_courses",
|
||||||
"assignment_details_list",
|
"assignment_details_list",
|
||||||
"learning_path_url",
|
"learning_path_url",
|
||||||
|
"cockpit_url",
|
||||||
"competence_url",
|
"competence_url",
|
||||||
"media_library_url",
|
"media_library_url",
|
||||||
"course_url",
|
"course_url",
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ class LearningPath(CourseBasePage):
|
||||||
def get_frontend_url(self):
|
def get_frontend_url(self):
|
||||||
return f"/course/{self.slug.replace('-lp', '')}/learn"
|
return f"/course/{self.slug.replace('-lp', '')}/learn"
|
||||||
|
|
||||||
|
def get_cockpit_url(self):
|
||||||
|
return f"/course/{self.slug.replace('-lp', '')}/cockpit"
|
||||||
|
|
||||||
|
|
||||||
class Topic(CourseBasePage):
|
class Topic(CourseBasePage):
|
||||||
serialize_field_names = ["is_visible"]
|
serialize_field_names = ["is_visible"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue