152 lines
4.3 KiB
TypeScript
152 lines
4.3 KiB
TypeScript
import { itGetCached, itPost } from "@/fetchHelpers";
|
|
import { deleteCircleDocument } from "@/services/files";
|
|
import type { CircleDocument, CircleExpert, CourseSession } from "@/types";
|
|
import _ from "lodash";
|
|
import log from "loglevel";
|
|
|
|
import { defineStore } from "pinia";
|
|
import { computed, ref } from "vue";
|
|
import { useRoute } from "vue-router";
|
|
import { useCircleStore } from "./circle";
|
|
import { useUserStore } from "./user";
|
|
|
|
export type CourseSessionsStoreState = {
|
|
courseSessions: CourseSession[] | undefined;
|
|
};
|
|
|
|
export type LearningSequenceCircleDocument = {
|
|
id: number;
|
|
title: string;
|
|
documents: CircleDocument[];
|
|
};
|
|
|
|
function loadCourseSessionsData(reload = false) {
|
|
log.debug("loadCourseSessionsData called");
|
|
const courseSessions = ref<CourseSession[]>([]);
|
|
|
|
async function loadAndUpdate() {
|
|
courseSessions.value = await itGetCached(`/api/course/sessions/`, {
|
|
reload: reload,
|
|
});
|
|
if (!courseSessions.value) {
|
|
throw `No courseSessionData found for user`;
|
|
}
|
|
}
|
|
|
|
loadAndUpdate(); // this will be called asynchronously, but does not block
|
|
|
|
// returns the empty sessions array at first, then after loading populates the ref
|
|
return { courseSessions };
|
|
}
|
|
|
|
function userExpertCircles(
|
|
userId: number,
|
|
courseSessionForRoute: CourseSession | undefined
|
|
): CircleExpert[] {
|
|
if (!courseSessionForRoute) {
|
|
return [];
|
|
}
|
|
return courseSessionForRoute.experts.filter((expert) => expert.user_id === userId);
|
|
}
|
|
|
|
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 { courseSessions } = loadCourseSessionsData();
|
|
// these will become getters
|
|
const coursesFromCourseSessions = computed(() =>
|
|
_.uniqBy(courseSessions.value, "course.id")
|
|
);
|
|
const courseSessionForRoute = computed(() => {
|
|
const route = useRoute();
|
|
const routePath = decodeURI(route.path);
|
|
|
|
return courseSessions.value.find((cs) => {
|
|
return routePath.startsWith(cs.course_url);
|
|
});
|
|
});
|
|
const hasCockpit = computed(() => {
|
|
if (courseSessionForRoute.value) {
|
|
const userStore = useUserStore();
|
|
return (
|
|
courseSessionForRoute.value.experts.filter(
|
|
(expert) => expert.user_id === userStore.id
|
|
).length > 0
|
|
);
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
const canUploadCircleDocuments = computed(() => {
|
|
const userStore = useUserStore();
|
|
const circleStore = useCircleStore();
|
|
const expertCircles = userExpertCircles(userStore.id, courseSessionForRoute.value);
|
|
|
|
return (
|
|
expertCircles.filter(
|
|
(c) => c.circle_translation_key === circleStore.circle?.translation_key
|
|
).length > 0
|
|
);
|
|
});
|
|
|
|
const circleDocuments = computed(() => {
|
|
const circleStore = useCircleStore();
|
|
|
|
return circleStore.circle?.learningSequences
|
|
.map((ls) => ({ id: ls.id, title: ls.title, documents: [] }))
|
|
.map((ls: { id: number; title: string; documents: CircleDocument[] }) => {
|
|
if (courseSessionForRoute.value === undefined) {
|
|
return ls;
|
|
}
|
|
|
|
for (let document of courseSessionForRoute.value.documents) {
|
|
if (document.learning_sequence === ls.id) {
|
|
ls.documents.push(document);
|
|
}
|
|
}
|
|
return ls;
|
|
})
|
|
.filter((ls) => ls.documents.length > 0);
|
|
});
|
|
|
|
function addDocument(document: CircleDocument) {
|
|
courseSessionForRoute.value?.documents.push(document);
|
|
}
|
|
|
|
async function startUpload() {
|
|
log.debug("loadCourseSessionsData called");
|
|
courseSessions.value = await itPost(`/api/core/file/start`, {
|
|
file_type: "image/png",
|
|
file_name: "test.png",
|
|
});
|
|
}
|
|
|
|
async function removeDocument(documentId: number) {
|
|
await deleteCircleDocument(documentId);
|
|
|
|
if (courseSessionForRoute.value === undefined) {
|
|
return;
|
|
}
|
|
|
|
courseSessionForRoute.value.documents =
|
|
courseSessionForRoute.value?.documents.filter((d) => d.id !== documentId);
|
|
}
|
|
|
|
return {
|
|
courseSessions,
|
|
coursesFromCourseSessions,
|
|
courseSessionForRoute,
|
|
hasCockpit,
|
|
canUploadCircleDocuments,
|
|
circleDocuments,
|
|
addDocument,
|
|
startUpload,
|
|
removeDocument,
|
|
};
|
|
});
|