Merge branch 'dev' into fix/questions-toon-enkel-groep
This commit is contained in:
commit
73ca508ff3
5 changed files with 118 additions and 62 deletions
|
@ -1,12 +1,13 @@
|
||||||
import { getAssignmentRepository, getGroupRepository, getSubmissionRepository } from '../data/repositories.js';
|
import { getSubmissionRepository } from '../data/repositories.js';
|
||||||
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
||||||
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
||||||
import { mapToSubmission, mapToSubmissionDTO } from '../interfaces/submission.js';
|
import { mapToSubmission, mapToSubmissionDTO } from '../interfaces/submission.js';
|
||||||
import { SubmissionDTO } from '@dwengo-1/common/interfaces/submission';
|
import { SubmissionDTO } from '@dwengo-1/common/interfaces/submission';
|
||||||
import { fetchStudent } from './students.js';
|
import { fetchStudent } from './students.js';
|
||||||
import { getExistingGroupFromGroupDTO } from './groups.js';
|
import { fetchGroup, getExistingGroupFromGroupDTO } from './groups.js';
|
||||||
import { Submission } from '../entities/assignments/submission.entity.js';
|
import { Submission } from '../entities/assignments/submission.entity.js';
|
||||||
import { Language } from '@dwengo-1/common/util/language';
|
import { Language } from '@dwengo-1/common/util/language';
|
||||||
|
import { fetchAssignment } from './assignments.js';
|
||||||
|
|
||||||
export async function fetchSubmission(loId: LearningObjectIdentifier, submissionNumber: number): Promise<Submission> {
|
export async function fetchSubmission(loId: LearningObjectIdentifier, submissionNumber: number): Promise<Submission> {
|
||||||
const submissionRepository = getSubmissionRepository();
|
const submissionRepository = getSubmissionRepository();
|
||||||
|
@ -64,15 +65,18 @@ export async function getSubmissionsForLearningObjectAndAssignment(
|
||||||
groupId?: number
|
groupId?: number
|
||||||
): Promise<SubmissionDTO[]> {
|
): Promise<SubmissionDTO[]> {
|
||||||
const loId = new LearningObjectIdentifier(learningObjectHruid, language, version);
|
const loId = new LearningObjectIdentifier(learningObjectHruid, language, version);
|
||||||
const assignment = await getAssignmentRepository().findByClassIdAndAssignmentId(classId, assignmentId);
|
|
||||||
|
|
||||||
let submissions: Submission[];
|
try {
|
||||||
if (groupId !== undefined) {
|
let submissions: Submission[];
|
||||||
const group = await getGroupRepository().findByAssignmentAndGroupNumber(assignment!, groupId);
|
if (groupId !== undefined) {
|
||||||
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndGroup(loId, group!);
|
const group = await fetchGroup(classId, assignmentId, groupId);
|
||||||
} else {
|
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndGroup(loId, group);
|
||||||
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndAssignment(loId, assignment!);
|
} else {
|
||||||
|
const assignment = await fetchAssignment(classId, assignmentId);
|
||||||
|
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndAssignment(loId, assignment);
|
||||||
|
}
|
||||||
|
return submissions.map((s) => mapToSubmissionDTO(s));
|
||||||
|
} catch (_) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return submissions.map((s) => mapToSubmissionDTO(s));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,19 +34,21 @@
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
<v-expansion-panels v-model="expanded">
|
<div class="nav-scroll-area">
|
||||||
<using-query-result
|
<v-expansion-panels v-model="expanded">
|
||||||
:query-result="allLearningPathsResult"
|
<using-query-result
|
||||||
v-slot="learningPaths: { data: LearningPath[] }"
|
:query-result="allLearningPathsResult"
|
||||||
>
|
v-slot="learningPaths: { data: LearningPath[] }"
|
||||||
<DiscussionSideBarElement
|
>
|
||||||
v-for="learningPath in learningPaths.data"
|
<DiscussionSideBarElement
|
||||||
:path="learningPath"
|
v-for="learningPath in learningPaths.data"
|
||||||
:activeObjectId="'' as string"
|
:path="learningPath"
|
||||||
:key="learningPath.hruid"
|
:activeObjectId="'' as string"
|
||||||
/>
|
:key="learningPath.hruid"
|
||||||
</using-query-result>
|
/>
|
||||||
</v-expansion-panels>
|
</using-query-result>
|
||||||
|
</v-expansion-panels>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
<div class="control-bar-above-content">
|
<div class="control-bar-above-content">
|
||||||
|
@ -67,4 +69,10 @@
|
||||||
padding-top: 2%;
|
padding-top: 2%;
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-scroll-area {
|
||||||
|
overflow-y: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
import authService from "@/services/auth/auth-service.ts";
|
import authService from "@/services/auth/auth-service.ts";
|
||||||
import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts";
|
import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts";
|
||||||
import LearningPathGroupSelector from "@/views/learning-paths/LearningPathGroupSelector.vue";
|
import LearningPathGroupSelector from "@/views/learning-paths/LearningPathGroupSelector.vue";
|
||||||
import { useQuestionsGroupQuery, useQuestionsQuery } from "@/queries/questions";
|
import { useQuestionsQuery } from "@/queries/questions";
|
||||||
import type { QuestionsResponse } from "@/controllers/questions";
|
import type { QuestionsResponse } from "@/controllers/questions";
|
||||||
import type { LearningObjectIdentifierDTO } from "@dwengo-1/common/interfaces/learning-content";
|
import type { LearningObjectIdentifierDTO } from "@dwengo-1/common/interfaces/learning-content";
|
||||||
import QandA from "@/components/QandA.vue";
|
import QandA from "@/components/QandA.vue";
|
||||||
|
@ -163,11 +163,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const loID: LearningObjectIdentifierDTO = {
|
|
||||||
hruid: props.learningObjectHruid as string,
|
|
||||||
language: props.language,
|
|
||||||
};
|
|
||||||
|
|
||||||
const discussionLink = computed(
|
const discussionLink = computed(
|
||||||
() =>
|
() =>
|
||||||
"/discussion" +
|
"/discussion" +
|
||||||
|
@ -237,7 +232,7 @@
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
<div>
|
<div class="nav-scroll-area">
|
||||||
<using-query-result
|
<using-query-result
|
||||||
:query-result="learningObjectListQueryResult"
|
:query-result="learningObjectListQueryResult"
|
||||||
v-slot="learningObjects: { data: LearningObject[] }"
|
v-slot="learningObjects: { data: LearningObject[] }"
|
||||||
|
@ -430,4 +425,10 @@
|
||||||
.discussion-link a:hover {
|
.discussion-link a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-scroll-area {
|
||||||
|
overflow-y: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -18,6 +18,15 @@
|
||||||
version: number;
|
version: number;
|
||||||
group: { forGroup: number; assignmentNo: number; classId: string };
|
group: { forGroup: number; assignmentNo: number; classId: string };
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
function parseContent(content: string): SubmissionData {
|
||||||
|
if (content === "") {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(content);
|
||||||
|
}
|
||||||
|
|
||||||
const emit = defineEmits<(e: "update:submissionData", value: SubmissionData) => void>();
|
const emit = defineEmits<(e: "update:submissionData", value: SubmissionData) => void>();
|
||||||
|
|
||||||
const submissionQuery = useSubmissionsQuery(
|
const submissionQuery = useSubmissionsQuery(
|
||||||
|
@ -35,7 +44,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitSubmission(submission: SubmissionDTO): void {
|
function emitSubmission(submission: SubmissionDTO): void {
|
||||||
emitSubmissionData(JSON.parse(submission.content));
|
emitSubmissionData(parseContent(submission.content));
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(submissionQuery.data, () => {
|
watch(submissionQuery.data, () => {
|
||||||
|
@ -47,12 +56,13 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const lastSubmission = computed<SubmissionData>(() => {
|
const lastSubmission = computed<SubmissionData | undefined>(() => {
|
||||||
const submissions = submissionQuery.data.value;
|
const submissions = submissionQuery.data.value;
|
||||||
if (!submissions || submissions.length === 0) {
|
if (!submissions || submissions.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return JSON.parse(submissions[submissions.length - 1].content);
|
|
||||||
|
return parseContent(submissions[submissions.length - 1].content);
|
||||||
});
|
});
|
||||||
|
|
||||||
const showSubmissionTable = computed(() => props.submissionData !== undefined && props.submissionData.length > 0);
|
const showSubmissionTable = computed(() => props.submissionData !== undefined && props.submissionData.length > 0);
|
||||||
|
|
|
@ -89,6 +89,15 @@
|
||||||
props.selectedLearningPath.language !== parsedLearningPath.value.language),
|
props.selectedLearningPath.language !== parsedLearningPath.value.language),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const selectedLearningPathLink = computed(() => {
|
||||||
|
if (!props.selectedLearningPath) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const { hruid, language } = props.selectedLearningPath;
|
||||||
|
const startNode = props.selectedLearningPath.nodes.find((it) => it.start_node);
|
||||||
|
return `/learningPath/${hruid}/${language}/${startNode.learningobject_hruid}`;
|
||||||
|
});
|
||||||
|
|
||||||
function getErrorMessage(): string | null {
|
function getErrorMessage(): string | null {
|
||||||
if (postError.value) {
|
if (postError.value) {
|
||||||
return t(extractErrorMessage(postError.value));
|
return t(extractErrorMessage(postError.value));
|
||||||
|
@ -104,7 +113,43 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-card :title="props.selectedLearningPath ? t('editLearningPath') : t('newLearningPath')">
|
<v-card>
|
||||||
|
<template v-slot:title>
|
||||||
|
<div class="title-container">
|
||||||
|
<span class="title">{{
|
||||||
|
props.selectedLearningPath ? t("editLearningPath") : t("newLearningPath")
|
||||||
|
}}</span>
|
||||||
|
<span class="actions">
|
||||||
|
<v-btn
|
||||||
|
@click="uploadLearningPath"
|
||||||
|
prependIcon="mdi mdi-check"
|
||||||
|
:loading="isPostPending || isPutPending"
|
||||||
|
:disabled="parsedLearningPath.hruid === DEFAULT_LEARNING_PATH.hruid || isIdModified"
|
||||||
|
variant="text"
|
||||||
|
>
|
||||||
|
{{ props.selectedLearningPath ? t("saveChanges") : t("create") }}
|
||||||
|
</v-btn>
|
||||||
|
<button-with-confirmation
|
||||||
|
@confirm="deleteLearningPath"
|
||||||
|
:disabled="!props.selectedLearningPath"
|
||||||
|
:text="t('delete')"
|
||||||
|
color="red"
|
||||||
|
prependIcon="mdi mdi-delete"
|
||||||
|
:confirmQueryText="t('learningPathDeleteQuery')"
|
||||||
|
variant="text"
|
||||||
|
/>
|
||||||
|
<v-btn
|
||||||
|
:href="selectedLearningPathLink"
|
||||||
|
target="_blank"
|
||||||
|
prepend-icon="mdi mdi-open-in-new"
|
||||||
|
:disabled="!props.selectedLearningPath"
|
||||||
|
variant="text"
|
||||||
|
>
|
||||||
|
{{ t("open") }}
|
||||||
|
</v-btn>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template v-slot:text>
|
<template v-slot:text>
|
||||||
<json-editor-vue v-model="learningPath"></json-editor-vue>
|
<json-editor-vue v-model="learningPath"></json-editor-vue>
|
||||||
<v-alert
|
<v-alert
|
||||||
|
@ -115,33 +160,21 @@
|
||||||
:text="getErrorMessage()!"
|
:text="getErrorMessage()!"
|
||||||
></v-alert>
|
></v-alert>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:actions>
|
|
||||||
<v-btn
|
|
||||||
@click="uploadLearningPath"
|
|
||||||
prependIcon="mdi mdi-check"
|
|
||||||
:loading="isPostPending || isPutPending"
|
|
||||||
:disabled="parsedLearningPath.hruid === DEFAULT_LEARNING_PATH.hruid || isIdModified"
|
|
||||||
>
|
|
||||||
{{ props.selectedLearningPath ? t("saveChanges") : t("create") }}
|
|
||||||
</v-btn>
|
|
||||||
<button-with-confirmation
|
|
||||||
@confirm="deleteLearningPath"
|
|
||||||
:disabled="!props.selectedLearningPath"
|
|
||||||
:text="t('delete')"
|
|
||||||
color="red"
|
|
||||||
prependIcon="mdi mdi-delete"
|
|
||||||
:confirmQueryText="t('learningPathDeleteQuery')"
|
|
||||||
/>
|
|
||||||
<v-btn
|
|
||||||
:href="`/learningPath/${props.selectedLearningPath?.hruid}/${props.selectedLearningPath?.language}/start`"
|
|
||||||
target="_blank"
|
|
||||||
prepend-icon="mdi mdi-open-in-new"
|
|
||||||
:disabled="!props.selectedLearningPath"
|
|
||||||
>
|
|
||||||
{{ t("open") }}
|
|
||||||
</v-btn>
|
|
||||||
</template>
|
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.title-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue