merge: merge fix/183-post-assignment into dev

This commit is contained in:
Adriaan Jacquet 2025-04-17 18:51:17 +02:00
commit 5a593cb88f
67 changed files with 2205 additions and 2129 deletions

View file

@ -6,6 +6,22 @@ export class AssignmentRepository extends DwengoEntityRepository<Assignment> {
public async findByClassAndId(within: Class, id: number): Promise<Assignment | null> {
return this.findOne({ within: within, id: id }, { populate: [ "groups", "groups.members" ]});
}
public async findByClassIdAndAssignmentId(withinClass: string, id: number): Promise<Assignment | null> {
return this.findOne({ within: { classId: withinClass }, id: id });
}
public async findAllByResponsibleTeacher(teacherUsername: string): Promise<Assignment[]> {
return this.findAll({
where: {
within: {
teachers: {
$some: {
username: teacherUsername,
},
},
},
},
});
}
public async findAllAssignmentsInClass(within: Class): Promise<Assignment[]> {
return this.findAll({ where: { within: within }, populate: [ "groups", "groups.members" ] });
}

View file

@ -3,6 +3,7 @@ import { Group } from '../../entities/assignments/group.entity.js';
import { Submission } from '../../entities/assignments/submission.entity.js';
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
import { Student } from '../../entities/users/student.entity.js';
import { Assignment } from '../../entities/assignments/assignment.entity';
export class SubmissionRepository extends DwengoEntityRepository<Submission> {
public async findSubmissionByLearningObjectAndSubmissionNumber(
@ -50,11 +51,58 @@ export class SubmissionRepository extends DwengoEntityRepository<Submission> {
}
public async findAllSubmissionsForGroup(group: Group): Promise<Submission[]> {
return this.find({ onBehalfOf: group });
return this.find(
{ onBehalfOf: group },
{
populate: ['onBehalfOf.members'],
}
);
}
/**
* Looks up all submissions for the given learning object which were submitted as part of the given assignment.
* When forStudentUsername is set, only the submissions of the given user's group are shown.
*/
public async findAllSubmissionsForLearningObjectAndAssignment(
loId: LearningObjectIdentifier,
assignment: Assignment,
forStudentUsername?: string
): Promise<Submission[]> {
const onBehalfOf = forStudentUsername
? {
assignment,
members: {
$some: {
username: forStudentUsername,
},
},
}
: {
assignment,
};
return this.findAll({
where: {
learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language,
learningObjectVersion: loId.version,
onBehalfOf,
},
});
}
public async findAllSubmissionsForStudent(student: Student): Promise<Submission[]> {
return this.find({ submitter: student });
const result = await this.find(
{ submitter: student },
{
populate: ['onBehalfOf.members'],
}
);
// Workaround: For some reason, without this MikroORM generates an UPDATE query with a syntax error in some tests
this.em.clear();
return result;
}
public async deleteSubmissionByLearningObjectAndSubmissionNumber(loId: LearningObjectIdentifier, submissionNumber: number): Promise<void> {

View file

@ -2,14 +2,14 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
import { Class } from '../../entities/classes/class.entity.js';
import { ClassJoinRequest } from '../../entities/classes/class-join-request.entity.js';
import { Student } from '../../entities/users/student.entity.js';
import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request';
import { ClassStatus } from '@dwengo-1/common/util/class-join-request';
export class ClassJoinRequestRepository extends DwengoEntityRepository<ClassJoinRequest> {
public async findAllRequestsBy(requester: Student): Promise<ClassJoinRequest[]> {
return this.findAll({ where: { requester: requester } });
}
public async findAllOpenRequestsTo(clazz: Class): Promise<ClassJoinRequest[]> {
return this.findAll({ where: { class: clazz, status: ClassJoinRequestStatus.Open } }); // TODO check if works like this
return this.findAll({ where: { class: clazz, status: ClassStatus.Open } }); // TODO check if works like this
}
public async findByStudentAndClass(requester: Student, clazz: Class): Promise<ClassJoinRequest | null> {
return this.findOne({ requester, class: clazz });

View file

@ -2,6 +2,7 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
import { Class } from '../../entities/classes/class.entity.js';
import { TeacherInvitation } from '../../entities/classes/teacher-invitation.entity.js';
import { Teacher } from '../../entities/users/teacher.entity.js';
import { ClassStatus } from '@dwengo-1/common/util/class-join-request';
export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherInvitation> {
public async findAllInvitationsForClass(clazz: Class): Promise<TeacherInvitation[]> {
@ -11,7 +12,7 @@ export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherI
return this.findAll({ where: { sender: sender } });
}
public async findAllInvitationsFor(receiver: Teacher): Promise<TeacherInvitation[]> {
return this.findAll({ where: { receiver: receiver } });
return this.findAll({ where: { receiver: receiver, status: ClassStatus.Open } });
}
public async deleteBy(clazz: Class, sender: Teacher, receiver: Teacher): Promise<void> {
return this.deleteWhere({
@ -20,4 +21,11 @@ export class TeacherInvitationRepository extends DwengoEntityRepository<TeacherI
class: clazz,
});
}
public async findBy(clazz: Class, sender: Teacher, receiver: Teacher): Promise<TeacherInvitation | null> {
return this.findOne({
sender: sender,
receiver: receiver,
class: clazz,
});
}
}

View file

@ -5,15 +5,16 @@ import { Student } from '../../entities/users/student.entity.js';
import { LearningObject } from '../../entities/content/learning-object.entity.js';
import { Assignment } from '../../entities/assignments/assignment.entity.js';
import { Loaded } from '@mikro-orm/core';
import {Group} from "../../entities/assignments/group.entity";
import { Group } from '../../entities/assignments/group.entity';
export class QuestionRepository extends DwengoEntityRepository<Question> {
public async createQuestion(question: { loId: LearningObjectIdentifier; author: Student; content: string }): Promise<Question> {
public async createQuestion(question: { loId: LearningObjectIdentifier; author: Student; inGroup: Group; content: string }): Promise<Question> {
const questionEntity = this.create({
learningObjectHruid: question.loId.hruid,
learningObjectLanguage: question.loId.language,
learningObjectVersion: question.loId.version,
author: question.author,
inGroup: question.inGroup,
content: question.content,
timestamp: new Date(),
});
@ -21,6 +22,7 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
questionEntity.learningObjectLanguage = question.loId.language;
questionEntity.learningObjectVersion = question.loId.version;
questionEntity.author = question.author;
questionEntity.inGroup = question.inGroup;
questionEntity.content = question.content;
return this.insert(questionEntity);
}
@ -60,7 +62,9 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
public async findAllByAssignment(assignment: Assignment): Promise<Question[]> {
return this.find({
author: assignment.groups.toArray<Group>().flatMap((group) => group.members),
inGroup: {
$contained: assignment.groups,
},
learningObjectHruid: assignment.learningPathHruid,
learningObjectLanguage: assignment.learningPathLanguage,
});
@ -73,6 +77,38 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
});
}
/**
* Looks up all questions for the given learning object which were asked as part of the given assignment.
* When forStudentUsername is set, only the questions within the given user's group are shown.
*/
public async findAllQuestionsAboutLearningObjectInAssignment(
loId: LearningObjectIdentifier,
assignment: Assignment,
forStudentUsername?: string
): Promise<Question[]> {
const inGroup = forStudentUsername
? {
assignment,
members: {
$some: {
username: forStudentUsername,
},
},
}
: {
assignment,
};
return this.findAll({
where: {
learningObjectHruid: loId.hruid,
learningObjectLanguage: loId.language,
learningObjectVersion: loId.version,
inGroup,
},
});
}
public async findByLearningObjectAndSequenceNumber(loId: LearningObjectIdentifier, sequenceNumber: number): Promise<Loaded<Question> | null> {
return this.findOne({
learningObjectHruid: loId.hruid,