Add frontend types and loading code for Assignment

This commit is contained in:
Daniel Egger 2023-04-05 17:01:54 +02:00
parent 8f84ef7502
commit d92b324f8e
6 changed files with 151 additions and 42 deletions

View File

@ -6,6 +6,7 @@ import log from "loglevel";
import type { Component } from "vue";
import { computed } from "vue";
import AssignmentBlock from "@/pages/learningPath/learningContentPage/blocks/AssignmentBlock.vue";
import AttendanceDayBlock from "@/pages/learningPath/learningContentPage/blocks/AttendanceDayBlock.vue";
import DescriptionBlock from "./blocks/DescriptionBlock.vue";
import DescriptionTextBlock from "./blocks/DescriptionTextBlock.vue";
@ -35,7 +36,7 @@ const block = computed(() => {
const COMPONENTS: Record<LearningContentType, Component> = {
placeholder: PlaceholderBlock,
video: VideoBlock,
assignment: DescriptionTextBlock,
assignment: AssignmentBlock,
resource: DescriptionTextBlock,
exercise: IframeBlock,
test: IframeBlock,

View File

@ -0,0 +1,40 @@
<template>
<div class="container-medium">
<div v-if="assignment" class="lg:mt-12">
<h2>Einleitung</h2>
<h3 class="mt-8">Ausgangslage</h3>
<p>{{ assignment.starting_position }}</p>
<pre class="mt-16">
{{ assignment }}
</pre>
</div>
</div>
</template>
<script setup lang="ts">
import { useAssignmentStore } from "@/stores/assignmentStore";
import type { Assignment, LearningContent } from "@/types";
import * as log from "loglevel";
import { onMounted, ref } from "vue";
const assignmentStore = useAssignmentStore();
const assignment = ref<Assignment>();
const props = defineProps<{
assignmentId: number;
learningContent: LearningContent;
}>();
onMounted(async () => {
log.debug("AssignmentView mounted", props.assignmentId, props.learningContent);
try {
assignment.value = await assignmentStore.loadAssignment(props.assignmentId);
} catch (error) {
log.error(error);
}
});
</script>

View File

@ -0,0 +1,21 @@
<template>
<AssignmentView
:assignment-id="props.value.assignment"
:learning-content="props.content"
/>
</template>
<script setup lang="ts">
import AssignmentView from "@/pages/learningPath/learningContentPage/assignment/AssignmentView.vue";
import type { LearningContent } from "@/types";
interface Value {
description: string;
assignment: number;
}
const props = defineProps<{
value: Value;
content: LearningContent;
}>();
</script>

View File

@ -0,0 +1,31 @@
import { itGet } from "@/fetchHelpers";
import type { Assignment } from "@/types";
import log from "loglevel";
import { defineStore } from "pinia";
export type AssignmentStoreState = {
assignment: Assignment | undefined;
};
export const useAssignmentStore = defineStore({
id: "assignmentStore",
state: () => {
return {
assignment: undefined,
} as AssignmentStoreState;
},
getters: {},
actions: {
async loadAssignment(assignmentId: number) {
log.debug("load assignment", assignmentId);
const assignmentData = await itGet(`/api/course/page/${assignmentId}/`);
if (!assignmentData) {
throw `No assignment found with: ${assignmentId}`;
}
this.assignment = assignmentData;
return this.assignment;
},
},
});

View File

@ -1,41 +0,0 @@
import { itGet } from "@/fetchHelpers";
import type { MediaLibraryPage } from "@/types";
import log from "loglevel";
import { defineStore } from "pinia";
export type MediaLibraryStoreState = {
mediaLibraryPage: MediaLibraryPage | undefined;
selectedLearningPath: { id: number; name: string };
availableLearningPaths: { id: number; name: string }[];
};
export const useMediaLibraryStore = defineStore({
id: "mediaLibrary",
state: () => {
return {
mediaLibraryPage: undefined,
selectedLearningPath: { id: 1, name: "Alle Lehrgänge" },
availableLearningPaths: [
{ id: 1, name: "Alle Lehrgänge" },
{ id: 2, name: "Versicherungsvermittler/-in" },
],
} as MediaLibraryStoreState;
},
getters: {},
actions: {
async loadMediaLibraryPage(slug: string, reload = false) {
if (this.mediaLibraryPage && !reload) {
return this.mediaLibraryPage;
}
log.debug("load mediaLibraryPageData");
const mediaLibraryPageData = await itGet(`/api/course/page/${slug}/`);
if (!mediaLibraryPageData) {
throw `No mediaLibraryPageData found with: ${slug}`;
}
this.mediaLibraryPage = mediaLibraryPageData;
return this.mediaLibraryPage;
},
},
});

View File

@ -285,6 +285,63 @@ export interface MediaLibraryPage extends BaseCourseWagtailPage {
readonly children: MediaCategoryPage[];
}
export interface AssignmentPerformanceObjective {
readonly type: "performance_objective";
readonly id: string;
readonly value: {
text: string;
};
}
export interface AssignmentTaskBlockExplanation {
readonly type: "explanation";
readonly id: string;
readonly value: {
readonly text: string;
};
}
export interface AssignmentTaskBlockUserConfirmation {
readonly type: "user_confirmation";
readonly id: string;
readonly value: {
readonly text: string;
};
}
export interface AssignmentTaskBlockUserTextInput {
readonly type: "user_text_input";
readonly id: string;
readonly value: {
readonly text?: string;
};
}
export type AssignmentTaskBlock =
| AssignmentTaskBlockExplanation
| AssignmentTaskBlockUserConfirmation
| AssignmentTaskBlockUserTextInput;
export interface AssignmentTask {
readonly type: "task";
readonly id: string;
readonly value: {
title: string;
file_submission_required: boolean;
content: AssignmentTaskBlock[];
};
}
export interface Assignment extends BaseCourseWagtailPage {
readonly type: "assignment.Assignment";
readonly starting_position: string;
readonly effort_required: string;
readonly performance_objectives: AssignmentPerformanceObjective[];
readonly assessment_description: string;
readonly assessment_document_url: string;
readonly tasks: AssignmentTask[];
}
export interface PerformanceCriteria extends BaseCourseWagtailPage {
readonly type: "competence.PerformanceCriteria";
readonly competence_id: string;