Refactor document handling

This commit is contained in:
Daniel Egger 2023-10-06 18:06:08 +02:00
parent f75590dd0b
commit 000e963730
10 changed files with 148 additions and 74 deletions

View File

@ -20,7 +20,7 @@ const documents = {
"\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument,
"\n query courseQuery($courseId: ID!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, "\n query courseQuery($courseId: ID!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument,
"\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument, "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument,
"\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n }\n }\n": types.CourseSessionDetailDocument, "\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n documents {\n id\n name\n file_name\n url\n learning_sequence {\n id\n title\n circle {\n id\n slug\n title\n }\n }\n }\n }\n }\n": types.CourseSessionDetailDocument,
"\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, "\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument,
}; };
@ -69,7 +69,7 @@ export function graphql(source: "\n query competenceCertificateQuery($courseSlu
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n }\n }\n"]; export function graphql(source: "\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n documents {\n id\n name\n file_name\n url\n learning_sequence {\n id\n title\n circle {\n id\n slug\n title\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query courseSessionDetail($courseSessionId: ID!) {\n course_session(id: $courseSessionId) {\n id\n title\n course {\n id\n title\n slug\n }\n users {\n id\n user_id\n first_name\n last_name\n email\n avatar_url\n role\n circles {\n id\n title\n slug\n }\n }\n attendance_courses {\n id\n location\n trainer\n due_date {\n id\n start\n end\n }\n learning_content_id\n learning_content {\n id\n title\n circle {\n id\n title\n slug\n }\n }\n }\n assignments {\n id\n submission_deadline {\n id\n start\n }\n evaluation_deadline {\n id\n start\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n edoniq_tests {\n id\n deadline {\n id\n start\n end\n }\n learning_content {\n id\n title\n content_assignment {\n id\n title\n assignment_type\n }\n }\n }\n documents {\n id\n name\n file_name\n url\n learning_sequence {\n id\n title\n circle {\n id\n slug\n title\n }\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */

File diff suppressed because one or more lines are too long

View File

@ -326,6 +326,7 @@ type CourseSessionObjectType {
attendance_courses: [CourseSessionAttendanceCourseObjectType] attendance_courses: [CourseSessionAttendanceCourseObjectType]
assignments: [CourseSessionAssignmentObjectType] assignments: [CourseSessionAssignmentObjectType]
edoniq_tests: [CourseSessionEdoniqTestObjectType] edoniq_tests: [CourseSessionEdoniqTestObjectType]
documents: [CircleDocumentObjectType]
users: [CourseSessionUserObjectsType] users: [CourseSessionUserObjectsType]
} }
@ -421,9 +422,9 @@ type CourseSessionAssignmentObjectType {
type CourseSessionEdoniqTestObjectType { type CourseSessionEdoniqTestObjectType {
id: ID! id: ID!
learning_content: LearningContentEdoniqTestObjectType learning_content: LearningContentEdoniqTestObjectType
deadline: DueDateObjectType
course_session_id: ID course_session_id: ID
learning_content_id: ID learning_content_id: ID
deadline: DueDateObjectType
} }
type LearningContentEdoniqTestObjectType implements LearningContentInterface { type LearningContentEdoniqTestObjectType implements LearningContentInterface {
@ -442,6 +443,15 @@ type LearningContentEdoniqTestObjectType implements LearningContentInterface {
content: String content: String
} }
type CircleDocumentObjectType {
id: UUID!
name: String!
course_session: CourseSessionObjectType!
learning_sequence: LearningSequenceObjectType!
file_name: String
url: String
}
type CourseSessionUserObjectsType { type CourseSessionUserObjectsType {
id: UUID! id: UUID!
role: String role: String

View File

@ -9,6 +9,7 @@ export const AttendanceUserInputType = "AttendanceUserInputType";
export const AttendanceUserObjectType = "AttendanceUserObjectType"; export const AttendanceUserObjectType = "AttendanceUserObjectType";
export const AttendanceUserStatus = "AttendanceUserStatus"; export const AttendanceUserStatus = "AttendanceUserStatus";
export const Boolean = "Boolean"; export const Boolean = "Boolean";
export const CircleDocumentObjectType = "CircleDocumentObjectType";
export const CircleObjectType = "CircleObjectType"; export const CircleObjectType = "CircleObjectType";
export const CompetenceCertificateListObjectType = "CompetenceCertificateListObjectType"; export const CompetenceCertificateListObjectType = "CompetenceCertificateListObjectType";
export const CompetenceCertificateObjectType = "CompetenceCertificateObjectType"; export const CompetenceCertificateObjectType = "CompetenceCertificateObjectType";

View File

@ -204,6 +204,21 @@ export const COURSE_SESSION_DETAIL_QUERY = graphql(`
} }
} }
} }
documents {
id
name
file_name
url
learning_sequence {
id
title
circle {
id
slug
title
}
}
}
} }
} }
`); `);

View File

@ -1,11 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { useCurrentCourseSession } from "@/composables"; import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue"; import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
import { useCockpitStore } from "@/stores/cockpit"; import { useCockpitStore } from "@/stores/cockpit";
import ItModal from "@/components/ui/ItModal.vue"; import ItModal from "@/components/ui/ItModal.vue";
import DocumentUploadForm from "@/pages/cockpit/documentPage/DocumentUploadForm.vue"; import DocumentUploadForm from "@/pages/cockpit/documentPage/DocumentUploadForm.vue";
import { computed, ref, watch } from "vue"; import { computed, ref, watch } from "vue";
import { useCircleStore } from "@/stores/circle";
import { useTranslation } from "i18next-vue"; import { useTranslation } from "i18next-vue";
import type { CircleDocument, DocumentUploadData } from "@/types"; import type { CircleDocument, DocumentUploadData } from "@/types";
import dialog from "@/utils/confirm-dialog"; import dialog from "@/utils/confirm-dialog";
@ -13,18 +12,21 @@ import log from "loglevel";
import { uploadCircleDocument } from "@/services/files"; import { uploadCircleDocument } from "@/services/files";
import { useCourseSessionsStore } from "@/stores/courseSessions"; import { useCourseSessionsStore } from "@/stores/courseSessions";
import DocumentListItem from "@/components/circle/DocumentListItem.vue"; import DocumentListItem from "@/components/circle/DocumentListItem.vue";
import { useCircleStore } from "@/stores/circle";
const cockpitStore = useCockpitStore(); const cockpitStore = useCockpitStore();
const courseSession = useCurrentCourseSession(); const courseSession = useCurrentCourseSession();
const circleStore = useCircleStore();
const courseSessionsStore = useCourseSessionsStore(); const courseSessionsStore = useCourseSessionsStore();
const courseSessionDetailResults = useCourseSessionDetailQuery();
const circleStore = useCircleStore();
const { t } = useTranslation(); const { t } = useTranslation();
const showUploadModal = ref(false); const showUploadModal = ref(false);
const showUploadErrorMessage = ref(false); const showUploadErrorMessage = ref(false);
const isUploading = ref(false); const isUploading = ref(false);
const dropdownLearningSequences = computed(() => const dropdownLearningSequences = computed(() =>
circleStore.circle?.learningSequences.map((sequence) => ({ circleStore.circle?.learningSequences.map((sequence) => ({
id: sequence.id, id: sequence.id,
@ -32,6 +34,14 @@ const dropdownLearningSequences = computed(() =>
})) }))
); );
const circleDocuments = computed(() => {
const documents =
courseSessionDetailResults.courseSessionDetail.value?.documents ?? [];
return documents.filter(
(d) => d.learning_sequence.circle.slug === cockpitStore.currentCircle?.slug
);
});
const deleteDocument = async (doc: CircleDocument) => { const deleteDocument = async (doc: CircleDocument) => {
const options = { const options = {
title: t("circlePage.documents.deleteModalTitle"), title: t("circlePage.documents.deleteModalTitle"),
@ -84,7 +94,7 @@ async function uploadDocument(data: DocumentUploadData) {
<div class="mb-9 flex flex-col lg:flex-row lg:items-center lg:justify-between"> <div class="mb-9 flex flex-col lg:flex-row lg:items-center lg:justify-between">
<h2>{{ t("a.Unterlagen für Teilnehmenden") }}</h2> <h2>{{ t("a.Unterlagen für Teilnehmenden") }}</h2>
<ItDropdownSelect <ItDropdownSelect
:model-value="cockpitStore.selectedCircle" :model-value="cockpitStore.currentCircle"
class="mt-4 w-full lg:mt-0 lg:w-96" class="mt-4 w-full lg:mt-0 lg:w-96"
:items="cockpitStore.circles" :items="cockpitStore.circles"
@update:model-value="cockpitStore.setCurrentCourseCircleFromEvent" @update:model-value="cockpitStore.setCurrentCourseCircleFromEvent"
@ -96,23 +106,15 @@ async function uploadDocument(data: DocumentUploadData) {
{{ t("circlePage.documents.action") }} {{ t("circlePage.documents.action") }}
</button> </button>
<ul <ul v-if="circleDocuments.length" class="mt-8 border-t border-t-gray-500">
v-if="courseSessionsStore.circleDocuments.length" <DocumentListItem
class="mt-8 border-t border-t-gray-500" v-for="doc of circleDocuments"
> :key="doc.url"
<template :subtitle="doc.learning_sequence.title"
v-for="learningSequence of courseSessionsStore.circleDocuments" :can-delete="true"
:key="learningSequence.id" :doc="doc"
> @delete="deleteDocument(doc)"
<DocumentListItem />
v-for="doc of learningSequence.documents"
:key="doc.url"
:subtitle="learningSequence.title"
:can-delete="courseSessionsStore.canUploadCircleDocuments"
:doc="doc"
@delete="deleteDocument(doc)"
/>
</template>
</ul> </ul>
</div> </div>
<ItModal v-model="showUploadModal"> <ItModal v-model="showUploadModal">

View File

@ -8,28 +8,31 @@
{{ $t("circlePage.documents.userDescription") }} {{ $t("circlePage.documents.userDescription") }}
</div> </div>
</div> </div>
<ul <ul v-if="circleDocuments.length" class="mt-8 border-t border-t-gray-500">
v-if="courseSessionsStore.circleDocuments.length" <DocumentListItem
class="mt-8 border-t border-t-gray-500" v-for="doc of circleDocuments"
> :key="doc.url"
<template :subtitle="doc.learning_sequence.title"
v-for="learningSequence of courseSessionsStore.circleDocuments" :doc="doc"
:key="learningSequence.id" />
>
<DocumentListItem
v-for="doc of learningSequence.documents"
:key="doc.url"
:subtitle="learningSequence.title"
:doc="doc"
/>
</template>
</ul> </ul>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useCourseSessionsStore } from "@/stores/courseSessions";
import DocumentListItem from "@/components/circle/DocumentListItem.vue"; import DocumentListItem from "@/components/circle/DocumentListItem.vue";
import { useCourseSessionDetailQuery } from "@/composables";
import { computed } from "vue";
import { useCircleStore } from "@/stores/circle";
const courseSessionsStore = useCourseSessionsStore(); const courseSessionDetailResults = useCourseSessionDetailQuery();
const circleStore = useCircleStore();
const circleDocuments = computed(() => {
const documents =
courseSessionDetailResults.courseSessionDetail.value?.documents ?? [];
return documents.filter(
(d) => d.learning_sequence.circle.slug === circleStore.circle?.slug
);
});
</script> </script>

View File

@ -1,6 +1,5 @@
import { itGetCached, itPost } from "@/fetchHelpers"; import { itGetCached } from "@/fetchHelpers";
import { deleteCircleDocument } from "@/services/files"; import type { CourseSession, DueDate } from "@/types";
import type { CircleDocument, CourseSession, DueDate } from "@/types";
import eventBus from "@/utils/eventBus"; import eventBus from "@/utils/eventBus";
import { useRouteLookups } from "@/utils/route"; import { useRouteLookups } from "@/utils/route";
import { useLocalStorage } from "@vueuse/core"; import { useLocalStorage } from "@vueuse/core";
@ -184,9 +183,9 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
); );
} }
function addDocument(document: CircleDocument) { // function addDocument(document: CircleDocument) {
currentCourseSession.value?.documents.push(document); // currentCourseSession.value?.documents.push(document);
} // }
function allDueDates() { function allDueDates() {
const allDueDatesReturn: DueDate[] = []; const allDueDatesReturn: DueDate[] = [];
@ -212,25 +211,25 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
}); });
} }
async function startUpload() { // async function startUpload() {
log.debug("loadCourseSessionsData called"); // log.debug("loadCourseSessionsData called");
allCourseSessions.value = await itPost(`/api/core/file/start`, { // allCourseSessions.value = await itPost(`/api/core/file/start`, {
file_type: "image/png", // file_type: "image/png",
file_name: "test.png", // file_name: "test.png",
}); // });
} // }
//
async function removeDocument(documentId: string) { // async function removeDocument(documentId: string) {
await deleteCircleDocument(documentId); // await deleteCircleDocument(documentId);
//
if (currentCourseSession.value === undefined) { // if (currentCourseSession.value === undefined) {
return; // return;
} // }
//
currentCourseSession.value.documents = currentCourseSession.value?.documents.filter( // currentCourseSession.value.documents = currentCourseSession.value?.documents.filter(
(d) => d.id !== documentId // (d) => d.id !== documentId
); // );
} // }
return { return {
uniqueCourseSessionsByCourse, uniqueCourseSessionsByCourse,
@ -241,9 +240,9 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => {
hasCockpit, hasCockpit,
hasCourseSessionPreview, hasCourseSessionPreview,
currentCourseSessionHasCockpit, currentCourseSessionHasCockpit,
addDocument, // addDocument,
startUpload, // startUpload,
removeDocument, // removeDocument,
allDueDates, allDueDates,
// use `useCurrentCourseSession` whenever possible // use `useCurrentCourseSession` whenever possible

View File

@ -462,8 +462,11 @@ export interface CircleDocument {
name: string; name: string;
file_name: string; file_name: string;
url: string; url: string;
course_session: number; learning_sequence: {
learning_sequence: number; id: string;
title: string;
circle: CircleLight;
};
} }
export interface CourseSessionAttendanceCourse { export interface CourseSessionAttendanceCourse {
@ -566,6 +569,7 @@ export interface CourseSessionDetail {
assignments: CourseSessionAssignment[]; assignments: CourseSessionAssignment[];
attendance_courses: CourseSessionAttendanceCourse[]; attendance_courses: CourseSessionAttendanceCourse[];
edoniq_tests: CourseSessionEdoniqTest[]; edoniq_tests: CourseSessionEdoniqTest[];
documents: CircleDocument[];
users: CourseSessionUser[]; users: CourseSessionUser[];
} }

View File

@ -13,6 +13,7 @@ from vbv_lernwelt.course.models import (
CoursePage, CoursePage,
CourseSession, CourseSession,
CourseSessionUser, CourseSessionUser,
CircleDocument,
) )
from vbv_lernwelt.course.permissions import has_course_access from vbv_lernwelt.course.permissions import has_course_access
from vbv_lernwelt.course_session.graphql.types import ( from vbv_lernwelt.course_session.graphql.types import (
@ -142,10 +143,34 @@ class CourseSessionUserObjectsType(DjangoObjectType):
return self.expert.all().values("id", "title", "slug", "translation_key") return self.expert.all().values("id", "title", "slug", "translation_key")
class CircleDocumentObjectType(DjangoObjectType):
file_name = graphene.String()
url = graphene.String()
class Meta:
model = CircleDocument
fields = [
"id",
"name",
"file_name",
"url",
"course_session",
"learning_sequence",
]
def resolve_file_name(self, info):
return self.file_name
def resolve_url(self, info):
return self.url
class CourseSessionObjectType(DjangoObjectType): class CourseSessionObjectType(DjangoObjectType):
attendance_courses = graphene.List(CourseSessionAttendanceCourseObjectType) attendance_courses = graphene.List(CourseSessionAttendanceCourseObjectType)
assignments = graphene.List(CourseSessionAssignmentObjectType) assignments = graphene.List(CourseSessionAssignmentObjectType)
edoniq_tests = graphene.List(CourseSessionEdoniqTestObjectType) edoniq_tests = graphene.List(CourseSessionEdoniqTestObjectType)
documents = graphene.List(CircleDocumentObjectType)
users = graphene.List(CourseSessionUserObjectsType) users = graphene.List(CourseSessionUserObjectsType)
class Meta: class Meta:
@ -158,7 +183,6 @@ class CourseSessionObjectType(DjangoObjectType):
"title", "title",
"start_date", "start_date",
"end_date", "end_date",
"attendance_courses",
"users", "users",
) )
@ -171,5 +195,10 @@ class CourseSessionObjectType(DjangoObjectType):
def resolve_edoniq_tests(self, info): def resolve_edoniq_tests(self, info):
return CourseSessionEdoniqTest.objects.filter(course_session=self) return CourseSessionEdoniqTest.objects.filter(course_session=self)
def resolve_documents(self, info):
return CircleDocument.objects.filter(
course_session=self, file__upload_finished_at__isnull=False
)
def resolve_users(self, info): def resolve_users(self, info):
return CourseSessionUser.objects.filter(course_session_id=self.id).distinct() return CourseSessionUser.objects.filter(course_session_id=self.id).distinct()