Merge branch 'dev' into extra/discussions
This commit is contained in:
commit
3c20b52b27
6 changed files with 115 additions and 69 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 { NotFoundException } from '../exceptions/not-found-exception.js';
|
||||
import { mapToSubmission, mapToSubmissionDTO } from '../interfaces/submission.js';
|
||||
import { SubmissionDTO } from '@dwengo-1/common/interfaces/submission';
|
||||
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 { Language } from '@dwengo-1/common/util/language';
|
||||
import { fetchAssignment } from './assignments.js';
|
||||
|
||||
export async function fetchSubmission(loId: LearningObjectIdentifier, submissionNumber: number): Promise<Submission> {
|
||||
const submissionRepository = getSubmissionRepository();
|
||||
|
@ -64,15 +65,18 @@ export async function getSubmissionsForLearningObjectAndAssignment(
|
|||
groupId?: number
|
||||
): Promise<SubmissionDTO[]> {
|
||||
const loId = new LearningObjectIdentifier(learningObjectHruid, language, version);
|
||||
const assignment = await getAssignmentRepository().findByClassIdAndAssignmentId(classId, assignmentId);
|
||||
|
||||
let submissions: Submission[];
|
||||
if (groupId !== undefined) {
|
||||
const group = await getGroupRepository().findByAssignmentAndGroupNumber(assignment!, groupId);
|
||||
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndGroup(loId, group!);
|
||||
} else {
|
||||
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndAssignment(loId, assignment!);
|
||||
try {
|
||||
let submissions: Submission[];
|
||||
if (groupId !== undefined) {
|
||||
const group = await fetchGroup(classId, assignmentId, groupId);
|
||||
submissions = await getSubmissionRepository().findAllSubmissionsForLearningObjectAndGroup(loId, group);
|
||||
} 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));
|
||||
}
|
||||
|
|
|
@ -38,12 +38,13 @@
|
|||
</template>
|
||||
</v-list-item>
|
||||
<v-divider></v-divider>
|
||||
<v-expansion-panels v-model="expanded">
|
||||
<using-query-result
|
||||
:query-result="allLearningPathsResult"
|
||||
v-slot="learningPaths: { data: LearningPath[] }"
|
||||
>
|
||||
<v-expansion-panel
|
||||
<div class="nav-scroll-area">
|
||||
<v-expansion-panels v-model="expanded">
|
||||
<using-query-result
|
||||
:query-result="allLearningPathsResult"
|
||||
v-slot="learningPaths: { data: LearningPath[] }"
|
||||
>
|
||||
<v-expansion-panel
|
||||
v-for="learningPath in learningPaths.data"
|
||||
:key="learningPath.hruid"
|
||||
:value="learningPath.hruid"
|
||||
|
@ -59,9 +60,10 @@
|
|||
/>
|
||||
</v-lazy>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</using-query-result>
|
||||
</v-expansion-panels>
|
||||
</v-expansion-panel>
|
||||
</using-query-result>
|
||||
</v-expansion-panels>
|
||||
</div>
|
||||
</div>
|
||||
</v-navigation-drawer>
|
||||
<div class="control-bar-above-content">
|
||||
|
@ -82,4 +84,10 @@
|
|||
padding-top: 2%;
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.nav-scroll-area {
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -14,7 +14,7 @@ export class QuestionController extends BaseController {
|
|||
loId: LearningObjectIdentifierDTO;
|
||||
|
||||
constructor(loId: LearningObjectIdentifierDTO) {
|
||||
super(`learningObject/${loId.hruid}/:${loId.version}/questions`);
|
||||
super(`learningObject/${loId.hruid}/${loId.version}/questions`);
|
||||
this.loId = loId;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,13 +13,11 @@
|
|||
import authService from "@/services/auth/auth-service.ts";
|
||||
import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts";
|
||||
import LearningPathGroupSelector from "@/views/learning-paths/LearningPathGroupSelector.vue";
|
||||
import { useCreateQuestionMutation, useQuestionsQuery } from "@/queries/questions";
|
||||
import { useQuestionsQuery } from "@/queries/questions";
|
||||
import type { QuestionsResponse } from "@/controllers/questions";
|
||||
import type { LearningObjectIdentifierDTO } from "@dwengo-1/common/interfaces/learning-content";
|
||||
import QandA from "@/components/QandA.vue";
|
||||
import type { QuestionDTO } from "@dwengo-1/common/interfaces/question";
|
||||
import { useStudentAssignmentsQuery, useStudentGroupsQuery } from "@/queries/students";
|
||||
import type { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment";
|
||||
import QuestionNotification from "@/components/QuestionNotification.vue";
|
||||
import QuestionBox from "@/components/QuestionBox.vue";
|
||||
import { AccountType } from "@dwengo-1/common/util/account-types";
|
||||
|
@ -147,19 +145,6 @@
|
|||
});
|
||||
}
|
||||
|
||||
const studentAssignmentsQueryResult = useStudentAssignmentsQuery(
|
||||
authService.authState.user?.profile.preferred_username,
|
||||
);
|
||||
|
||||
const loID: LearningObjectIdentifierDTO = {
|
||||
hruid: props.learningObjectHruid as string,
|
||||
language: props.language,
|
||||
};
|
||||
const createQuestionMutation = useCreateQuestionMutation(loID);
|
||||
const groupsQueryResult = useStudentGroupsQuery(authService.authState.user?.profile.preferred_username);
|
||||
|
||||
const questionInput = ref("");
|
||||
|
||||
const discussionLink = computed(
|
||||
() =>
|
||||
"/discussion" +
|
||||
|
@ -229,7 +214,7 @@
|
|||
</template>
|
||||
</v-list-item>
|
||||
<v-divider></v-divider>
|
||||
<div>
|
||||
<div class="nav-scroll-area">
|
||||
<using-query-result
|
||||
:query-result="learningObjectListQueryResult"
|
||||
v-slot="learningObjects: { data: LearningObject[] }"
|
||||
|
@ -417,4 +402,10 @@
|
|||
.discussion-link a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.nav-scroll-area {
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
version: number;
|
||||
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 submissionQuery = useSubmissionsQuery(
|
||||
|
@ -35,7 +44,7 @@
|
|||
}
|
||||
|
||||
function emitSubmission(submission: SubmissionDTO): void {
|
||||
emitSubmissionData(JSON.parse(submission.content));
|
||||
emitSubmissionData(parseContent(submission.content));
|
||||
}
|
||||
|
||||
watch(submissionQuery.data, () => {
|
||||
|
@ -47,12 +56,13 @@
|
|||
}
|
||||
});
|
||||
|
||||
const lastSubmission = computed<SubmissionData>(() => {
|
||||
const lastSubmission = computed<SubmissionData | undefined>(() => {
|
||||
const submissions = submissionQuery.data.value;
|
||||
if (!submissions || submissions.length === 0) {
|
||||
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);
|
||||
|
|
|
@ -89,6 +89,15 @@
|
|||
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 {
|
||||
if (postError.value) {
|
||||
return t(extractErrorMessage(postError.value));
|
||||
|
@ -104,7 +113,43 @@
|
|||
</script>
|
||||
|
||||
<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>
|
||||
<json-editor-vue v-model="learningPath"></json-editor-vue>
|
||||
<v-alert
|
||||
|
@ -115,33 +160,21 @@
|
|||
:text="getErrorMessage()!"
|
||||
></v-alert>
|
||||
</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>
|
||||
</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