Refactor loading of course sessions
This commit is contained in:
parent
c0407803fc
commit
44131f1d8b
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||||
|
import type { CourseSession } from "@/types";
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
export function useCurrentCourseSession(): CourseSession {
|
||||||
|
const store = useCourseSessionsStore();
|
||||||
|
const currentCourseSession = computed(() => store.currentCourseSession);
|
||||||
|
|
||||||
|
// This will always return a defined value, but you should still handle the case where currentCourseSession is undefined in the store.
|
||||||
|
if (!currentCourseSession.value) {
|
||||||
|
throw new Error("currentCourseSession is not defined in the store");
|
||||||
|
} else {
|
||||||
|
// return a non-reactive copy of the value
|
||||||
|
return currentCourseSession.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import DashboardPage from "@/pages/DashboardPage.vue";
|
import DashboardPage from "@/pages/DashboardPage.vue";
|
||||||
import LoginPage from "@/pages/LoginPage.vue";
|
import LoginPage from "@/pages/LoginPage.vue";
|
||||||
import { redirectToLoginIfRequired, updateLoggedIn } from "@/router/guards";
|
import { redirectToLoginIfRequired, updateLoggedIn } from "@/router/guards";
|
||||||
import { useAppStore } from "@/stores/app";
|
|
||||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
|
|
||||||
|
|
@ -182,18 +181,19 @@ const router = createRouter({
|
||||||
router.beforeEach(updateLoggedIn);
|
router.beforeEach(updateLoggedIn);
|
||||||
router.beforeEach(redirectToLoginIfRequired);
|
router.beforeEach(redirectToLoginIfRequired);
|
||||||
|
|
||||||
router.beforeEach((to) => {
|
router.beforeEach(async (to) => {
|
||||||
|
// register after login hooks
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
const courseSessionsStore = useCourseSessionsStore();
|
||||||
if (to.params.courseSlug) {
|
if (to.params.courseSlug) {
|
||||||
courseSessionsStore._currentCourseSlug = to.params.courseSlug as string;
|
courseSessionsStore._currentCourseSlug = to.params.courseSlug as string;
|
||||||
|
if (!courseSessionsStore.loaded) {
|
||||||
|
await courseSessionsStore.loadCourseSessionsData();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
courseSessionsStore._currentCourseSlug = "";
|
courseSessionsStore._currentCourseSlug = "";
|
||||||
|
// load async
|
||||||
|
courseSessionsStore.loadCourseSessionsData();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.afterEach(() => {
|
|
||||||
const appStore = useAppStore();
|
|
||||||
appStore.routingFinished = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import { defineStore } from "pinia";
|
|
||||||
|
|
||||||
export type AppState = {
|
|
||||||
userLoaded: boolean;
|
|
||||||
routingFinished: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useAppStore = defineStore({
|
|
||||||
id: "app",
|
|
||||||
state: () =>
|
|
||||||
({
|
|
||||||
userLoaded: false,
|
|
||||||
routingFinished: false,
|
|
||||||
} as AppState),
|
|
||||||
getters: {},
|
|
||||||
actions: {},
|
|
||||||
});
|
|
||||||
|
|
@ -25,12 +25,14 @@ export type LearningSequenceCircleDocument = {
|
||||||
|
|
||||||
const SELECTED_COURSE_SESSIONS_KEY = "selectedCourseSessionMap";
|
const SELECTED_COURSE_SESSIONS_KEY = "selectedCourseSessionMap";
|
||||||
|
|
||||||
function loadCourseSessionsData(reload = false) {
|
export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
log.debug("loadCourseSessionsData called");
|
const loaded = ref(false);
|
||||||
const courseSessions = ref<CourseSession[]>([]);
|
const allCourseSessions = ref<CourseSession[]>([]);
|
||||||
|
|
||||||
async function loadAndUpdate() {
|
async function loadCourseSessionsData(reload = false) {
|
||||||
courseSessions.value = await itGetCached(`/api/course/sessions/`, {
|
log.debug("loadCourseSessionsData called");
|
||||||
|
|
||||||
|
allCourseSessions.value = await itGetCached(`/api/course/sessions/`, {
|
||||||
reload: reload,
|
reload: reload,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -38,7 +40,7 @@ function loadCourseSessionsData(reload = false) {
|
||||||
if (userStore.loggedIn) {
|
if (userStore.loggedIn) {
|
||||||
// TODO: refactor after implementing of Klassenkonzept
|
// TODO: refactor after implementing of Klassenkonzept
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
courseSessions.value.map(async (cs) => {
|
allCourseSessions.value.map(async (cs) => {
|
||||||
const users = (await itGetCached(`/api/course/sessions/${cs.id}/users/`, {
|
const users = (await itGetCached(`/api/course/sessions/${cs.id}/users/`, {
|
||||||
reload: reload,
|
reload: reload,
|
||||||
})) as CourseSessionUser[];
|
})) as CourseSessionUser[];
|
||||||
|
|
@ -46,26 +48,14 @@ function loadCourseSessionsData(reload = false) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!courseSessions.value) {
|
if (!allCourseSessions.value) {
|
||||||
throw `No courseSessionData found for user`;
|
throw `No courseSessionData found for user`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loaded.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAndUpdate(); // this will be called asynchronously, but does not block
|
|
||||||
|
|
||||||
// returns the empty sessions array at first, then after loading populates the ref
|
|
||||||
return { allCourseSessions: courseSessions };
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
|
||||||
// using setup function seems cleaner, see https://pinia.vuejs.org/core-concepts/#setup-stores
|
|
||||||
|
|
||||||
// this will become a state variable (like each other `ref()`
|
|
||||||
|
|
||||||
// store should do own setup, we don't want to have each component initialize it
|
|
||||||
// that's why we call the load function in here
|
|
||||||
const { allCourseSessions } = loadCourseSessionsData();
|
|
||||||
const selectedCourseSessionMap = useLocalStorage(
|
const selectedCourseSessionMap = useLocalStorage(
|
||||||
SELECTED_COURSE_SESSIONS_KEY,
|
SELECTED_COURSE_SESSIONS_KEY,
|
||||||
new Map<string, number>()
|
new Map<string, number>()
|
||||||
|
|
@ -259,6 +249,8 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
|
||||||
findAssignmentDetails,
|
findAssignmentDetails,
|
||||||
|
|
||||||
// only used so that `router.afterEach` can switch it
|
// only used so that `router.afterEach` can switch it
|
||||||
|
loadCourseSessionsData,
|
||||||
|
loaded,
|
||||||
_currentCourseSlug,
|
_currentCourseSlug,
|
||||||
|
|
||||||
// only used for unit testing
|
// only used for unit testing
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import log from "loglevel";
|
||||||
|
|
||||||
import { bustItGetCache, itGetCached, itPost } from "@/fetchHelpers";
|
import { bustItGetCache, itGetCached, itPost } from "@/fetchHelpers";
|
||||||
import { loadLocaleMessages, setI18nLanguage } from "@/i18n";
|
import { loadLocaleMessages, setI18nLanguage } from "@/i18n";
|
||||||
import { useAppStore } from "@/stores/app";
|
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
const logoutRedirectUrl = import.meta.env.VITE_LOGOUT_REDIRECT || "/";
|
const logoutRedirectUrl = import.meta.env.VITE_LOGOUT_REDIRECT || "/";
|
||||||
|
|
@ -85,11 +84,9 @@ export const useUserStore = defineStore({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async fetchUser() {
|
async fetchUser() {
|
||||||
const appStore = useAppStore();
|
|
||||||
const data = await itGetCached("/api/core/me/");
|
const data = await itGetCached("/api/core/me/");
|
||||||
this.$state = data;
|
this.$state = data;
|
||||||
this.loggedIn = true;
|
this.loggedIn = true;
|
||||||
appStore.userLoaded = true;
|
|
||||||
await setLocale(data.language);
|
await setLocale(data.language);
|
||||||
},
|
},
|
||||||
async setUserLanguages(language: AvailableLanguages) {
|
async setUserLanguages(language: AvailableLanguages) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue