From 3375d0f1216a99524cb9e15b78aa123c2e57a0c6 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Mon, 12 Dec 2022 11:00:51 +0100 Subject: [PATCH 1/2] Return circle expert data, use circle data --- client/src/pages/cockpit/CockpitIndexPage.vue | 18 ++++++------- client/src/stores/cockpit.ts | 27 +++++++++++++------ client/src/types.ts | 12 ++++++++- server/vbv_lernwelt/course/models.py | 11 ++++++++ server/vbv_lernwelt/course/views.py | 24 ++++++++--------- 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/client/src/pages/cockpit/CockpitIndexPage.vue b/client/src/pages/cockpit/CockpitIndexPage.vue index 6ab48923..9bf737a3 100644 --- a/client/src/pages/cockpit/CockpitIndexPage.vue +++ b/client/src/pages/cockpit/CockpitIndexPage.vue @@ -37,14 +37,14 @@ const data = { const selectedCircle = ref(1); -function setActiveClasses(index: number) { - return selectedCircle.value === index +function setActiveClasses(id: number) { + return cockpitStore.selectedCircle === id ? ["bg-blue-900", "text-white"] : ["text-bg-900"]; } -function setActiveCircle(index: number) { - selectedCircle.value = index; +function setActiveCircle(id: number) { + cockpitStore.selectedCircle = id; } @@ -55,16 +55,16 @@ function setActiveCircle(index: number) {

{{ $t("general.circles") }}:

diff --git a/client/src/stores/cockpit.ts b/client/src/stores/cockpit.ts index 45c80af1..336874ca 100644 --- a/client/src/stores/cockpit.ts +++ b/client/src/stores/cockpit.ts @@ -1,11 +1,13 @@ import { itGetCached } from "@/fetchHelpers"; -import type { CourseSessionUser } from "@/types"; +import type { CourseSessionUser, ExpertSessionUser } from "@/types"; import log from "loglevel"; import { defineStore } from "pinia"; export type CockpitStoreState = { courseSessionUsers: CourseSessionUser[] | undefined; + cockpitSessionUser: ExpertSessionUser | undefined; + selectedCircle: number; }; export const useCockpitStore = defineStore({ @@ -13,18 +15,27 @@ export const useCockpitStore = defineStore({ state: () => { return { courseSessionUsers: undefined, + cockpitSessionUser: undefined, + selectedCircle: -1, } as CockpitStoreState; }, - getters: {}, + getters: { + circles: (state) => state.cockpitSessionUser?.circles, + }, actions: { async loadCourseSessionUsers(courseSlug: string, reload = false) { log.debug("loadCockpitData called"); - this.courseSessionUsers = await itGetCached( - `/api/course/sessions/${courseSlug}/users/`, - { - reload: reload, - } - ); + const data = await itGetCached(`/api/course/sessions/${courseSlug}/users/`, { + reload: reload, + }); + + this.courseSessionUsers = data.users; + this.cockpitSessionUser = data.cockpit_user; + + if (this.cockpitSessionUser.circles?.length > 0) { + this.selectedCircle = this.cockpitSessionUser.circles[0].id; + } + if (!this.courseSessionUsers) { throw `No courseSessionUsers data found for user`; } diff --git a/client/src/types.ts b/client/src/types.ts index 74f2fe4e..4878e623 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -329,6 +329,8 @@ export interface CourseSession { experts: CircleExpert[]; } +export type Role = "MEMBER" | "EXPERT" | "TUTOR"; + export interface CourseSessionUser { session_title: string; user_id: number; @@ -336,5 +338,13 @@ export interface CourseSessionUser { last_name: string; email: string; avatar_url: string; - role: "MEMBER" | "EXPERT" | "TUTOR"; + role: Role; +} + +export interface ExpertSessionUser extends CourseSessionUser { + role: "EXPERT"; + circles: { + id: number; + title: string; + }[]; } diff --git a/server/vbv_lernwelt/course/models.py b/server/vbv_lernwelt/course/models.py index ce71a404..3edd406a 100644 --- a/server/vbv_lernwelt/course/models.py +++ b/server/vbv_lernwelt/course/models.py @@ -224,3 +224,14 @@ class CourseSessionUser(models.Model): name="course_session_user_unique_course_session_user", ) ] + + def to_dict(self): + return { + "session_title": self.course_session.title, + "user_id": self.user.id, + "first_name": self.user.first_name, + "last_name": self.user.last_name, + "email": self.user.email, + "avatar_url": self.user.avatar_url, + "role": self.role, + } diff --git a/server/vbv_lernwelt/course/views.py b/server/vbv_lernwelt/course/views.py index b27e3e80..a5cc4558 100644 --- a/server/vbv_lernwelt/course/views.py +++ b/server/vbv_lernwelt/course/views.py @@ -129,18 +129,18 @@ def get_course_session_users(request, course_slug): course__slug=course_slug ) qs = CourseSessionUser.objects.filter(course_session__in=course_sessions) - data = [ - { - "session_title": csu.course_session.title, - "user_id": csu.user.id, - "first_name": csu.user.first_name, - "last_name": csu.user.last_name, - "email": csu.user.email, - "avatar_url": csu.user.avatar_url, - "role": csu.role, - } - for csu in qs - ] + cockpit_user_csu = qs.filter(user_id=request.user.id) + + if len(cockpit_user_csu) == 0: + return Response({"error": "User not found"}, status=404) + + user_data = [csu.to_dict() for csu in qs.exclude(user_id=request.user.id)] + + data = { + "cockpit_user": cockpit_user_csu[0].to_dict() + | {"circles": cockpit_user_csu[0].expert.all().values("id", "title")}, + "users": user_data, + } return Response(status=200, data=data) except PermissionDenied as e: From fd2aaadedb48e5436376dff24db0d666864e3af2 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Mon, 12 Dec 2022 13:22:24 +0100 Subject: [PATCH 2/2] Add conditional Cockpit link to navigation --- client/src/components/MainNavigationBar.vue | 15 ++++++++++++++- client/src/components/MobileMenu.vue | 4 ++-- client/src/locales/de.json | 1 + client/src/stores/courseSessions.ts | 9 +++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/client/src/components/MainNavigationBar.vue b/client/src/components/MainNavigationBar.vue index d313395b..80394067 100644 --- a/client/src/components/MainNavigationBar.vue +++ b/client/src/components/MainNavigationBar.vue @@ -183,7 +183,20 @@ const profileDropdownData: DropdownListItem[] = [ class="nav-item" :class="{ 'nav-item--active': inCompetenceProfile() }" > - KompetenzNavi + {{ $t("competences.title") }} + + + + {{ $t("cockpit.title") }} diff --git a/client/src/components/MobileMenu.vue b/client/src/components/MobileMenu.vue index 30dc5070..1dba6ae2 100644 --- a/client/src/components/MobileMenu.vue +++ b/client/src/components/MobileMenu.vue @@ -59,8 +59,8 @@ const clickLink = (to: string | undefined) => {
  • -
  • diff --git a/client/src/locales/de.json b/client/src/locales/de.json index 1b3470aa..fb2b953f 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -77,6 +77,7 @@ "faq": "FAQ" }, "cockpit": { + "title": "Cockpit", "tasksDone": "Erledigte Transferaufträge von Teilnehmer.", "feedbacksDone": "Abgeschickte Feedbacks von Teilnehmer.", "examsDone": "Abgelegte PrĂĽfungen von Teilnehmer.", diff --git a/client/src/stores/courseSessions.ts b/client/src/stores/courseSessions.ts index 0e726193..956f9d0d 100644 --- a/client/src/stores/courseSessions.ts +++ b/client/src/stores/courseSessions.ts @@ -5,6 +5,7 @@ import log from "loglevel"; import { defineStore } from "pinia"; import { useRoute } from "vue-router"; +import { useUserStore } from "./user"; export type CourseSessionsStoreState = { courseSessions: CourseSession[] | undefined; @@ -30,6 +31,14 @@ export const useCourseSessionsStore = defineStore({ return _.uniqBy(state.courseSessions, "course.id"); } }, + hasCockpit() { + const userStore = useUserStore(); + return ( + this.courseSessionForRoute.experts.filter( + (expert) => expert.user_id === userStore.id + ).length > 0 + ); + }, }, actions: { async loadCourseSessionsData(reload = false) {