Merge pull request #214 from SELab-2/fix/213-assignment-and-group-questions
fix: Assignments en group questions
This commit is contained in:
commit
21022efb1e
6 changed files with 79 additions and 42 deletions
|
@ -4,6 +4,7 @@ import {
|
||||||
deleteAssignment,
|
deleteAssignment,
|
||||||
getAllAssignments,
|
getAllAssignments,
|
||||||
getAssignment,
|
getAssignment,
|
||||||
|
getAssignmentsQuestions,
|
||||||
getAssignmentsSubmissions,
|
getAssignmentsSubmissions,
|
||||||
putAssignment,
|
putAssignment,
|
||||||
} from '../services/assignments.js';
|
} from '../services/assignments.js';
|
||||||
|
@ -13,6 +14,19 @@ import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||||
import { Assignment } from '../entities/assignments/assignment.entity.js';
|
import { Assignment } from '../entities/assignments/assignment.entity.js';
|
||||||
import { EntityDTO } from '@mikro-orm/core';
|
import { EntityDTO } from '@mikro-orm/core';
|
||||||
|
|
||||||
|
function getAssignmentParams(req: Request): { classid: string; assignmentNumber: number; full: boolean } {
|
||||||
|
const classid = req.params.classid;
|
||||||
|
const assignmentNumber = Number(req.params.id);
|
||||||
|
const full = req.query.full === 'true';
|
||||||
|
requireFields({ assignmentNumber, classid });
|
||||||
|
|
||||||
|
if (isNaN(assignmentNumber)) {
|
||||||
|
throw new BadRequestException('Assignment id should be a number');
|
||||||
|
}
|
||||||
|
|
||||||
|
return { classid, assignmentNumber, full };
|
||||||
|
}
|
||||||
|
|
||||||
export async function getAllAssignmentsHandler(req: Request, res: Response): Promise<void> {
|
export async function getAllAssignmentsHandler(req: Request, res: Response): Promise<void> {
|
||||||
const classId = req.params.classid;
|
const classId = req.params.classid;
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
@ -38,58 +52,42 @@ export async function createAssignmentHandler(req: Request, res: Response): Prom
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAssignmentHandler(req: Request, res: Response): Promise<void> {
|
export async function getAssignmentHandler(req: Request, res: Response): Promise<void> {
|
||||||
const id = Number(req.params.id);
|
const { classid, assignmentNumber } = getAssignmentParams(req);
|
||||||
const classid = req.params.classid;
|
|
||||||
requireFields({ id, classid });
|
|
||||||
|
|
||||||
if (isNaN(id)) {
|
const assignment = await getAssignment(classid, assignmentNumber);
|
||||||
throw new BadRequestException('Assignment id should be a number');
|
|
||||||
}
|
|
||||||
|
|
||||||
const assignment = await getAssignment(classid, id);
|
|
||||||
|
|
||||||
res.json({ assignment });
|
res.json({ assignment });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function putAssignmentHandler(req: Request, res: Response): Promise<void> {
|
export async function putAssignmentHandler(req: Request, res: Response): Promise<void> {
|
||||||
const id = Number(req.params.id);
|
const { classid, assignmentNumber } = getAssignmentParams(req);
|
||||||
const classid = req.params.classid;
|
|
||||||
requireFields({ id, classid });
|
|
||||||
|
|
||||||
if (isNaN(id)) {
|
|
||||||
throw new BadRequestException('Assignment id should be a number');
|
|
||||||
}
|
|
||||||
|
|
||||||
const assignmentData = req.body as Partial<EntityDTO<Assignment>>;
|
const assignmentData = req.body as Partial<EntityDTO<Assignment>>;
|
||||||
const assignment = await putAssignment(classid, id, assignmentData);
|
const assignment = await putAssignment(classid, assignmentNumber, assignmentData);
|
||||||
|
|
||||||
res.json({ assignment });
|
res.json({ assignment });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteAssignmentHandler(req: Request, res: Response): Promise<void> {
|
export async function deleteAssignmentHandler(req: Request, res: Response): Promise<void> {
|
||||||
const id = Number(req.params.id);
|
const { classid, assignmentNumber } = getAssignmentParams(req);
|
||||||
const classid = req.params.classid;
|
|
||||||
requireFields({ id, classid });
|
|
||||||
|
|
||||||
if (isNaN(id)) {
|
const assignment = await deleteAssignment(classid, assignmentNumber);
|
||||||
throw new BadRequestException('Assignment id should be a number');
|
|
||||||
}
|
|
||||||
|
|
||||||
const assignment = await deleteAssignment(classid, id);
|
|
||||||
res.json({ assignment });
|
res.json({ assignment });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAssignmentsSubmissionsHandler(req: Request, res: Response): Promise<void> {
|
export async function getAssignmentsSubmissionsHandler(req: Request, res: Response): Promise<void> {
|
||||||
const classid = req.params.classid;
|
const { classid, assignmentNumber, full } = getAssignmentParams(req);
|
||||||
const assignmentNumber = Number(req.params.id);
|
|
||||||
const full = req.query.full === 'true';
|
|
||||||
requireFields({ assignmentNumber, classid });
|
|
||||||
|
|
||||||
if (isNaN(assignmentNumber)) {
|
|
||||||
throw new BadRequestException('Assignment id should be a number');
|
|
||||||
}
|
|
||||||
|
|
||||||
const submissions = await getAssignmentsSubmissions(classid, assignmentNumber, full);
|
const submissions = await getAssignmentsSubmissions(classid, assignmentNumber, full);
|
||||||
|
|
||||||
res.json({ submissions });
|
res.json({ submissions });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getAssignmentQuestionsHandler(req: Request, res: Response): Promise<void> {
|
||||||
|
const { classid, assignmentNumber, full } = getAssignmentParams(req);
|
||||||
|
|
||||||
|
const questions = await getAssignmentsQuestions(classid, assignmentNumber, full);
|
||||||
|
|
||||||
|
res.json({ questions });
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { createGroup, deleteGroup, getAllGroups, getGroup, getGroupSubmissions, putGroup } from '../services/groups.js';
|
import { createGroup, deleteGroup, getAllGroups, getGroup, getGroupQuestions, getGroupSubmissions, putGroup } from '../services/groups.js';
|
||||||
import { GroupDTO } from '@dwengo-1/common/interfaces/group';
|
import { GroupDTO } from '@dwengo-1/common/interfaces/group';
|
||||||
import { requireFields } from './error-helper.js';
|
import { requireFields } from './error-helper.js';
|
||||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||||
|
@ -84,7 +84,7 @@ export async function createGroupHandler(req: Request, res: Response): Promise<v
|
||||||
res.status(201).json({ group });
|
res.status(201).json({ group });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGroupSubmissionsHandler(req: Request, res: Response): Promise<void> {
|
function getGroupParams(req: Request): { classId: string; assignmentId: number; groupId: number; full: boolean } {
|
||||||
const classId = req.params.classid;
|
const classId = req.params.classid;
|
||||||
const assignmentId = Number(req.params.assignmentid);
|
const assignmentId = Number(req.params.assignmentid);
|
||||||
const groupId = Number(req.params.groupid);
|
const groupId = Number(req.params.groupid);
|
||||||
|
@ -100,7 +100,21 @@ export async function getGroupSubmissionsHandler(req: Request, res: Response): P
|
||||||
throw new BadRequestException('Group id must be a number');
|
throw new BadRequestException('Group id must be a number');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { classId, assignmentId, groupId, full };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getGroupSubmissionsHandler(req: Request, res: Response): Promise<void> {
|
||||||
|
const { classId, assignmentId, groupId, full } = getGroupParams(req);
|
||||||
|
|
||||||
const submissions = await getGroupSubmissions(classId, assignmentId, groupId, full);
|
const submissions = await getGroupSubmissions(classId, assignmentId, groupId, full);
|
||||||
|
|
||||||
res.json({ submissions });
|
res.json({ submissions });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getGroupQuestionsHandler(req: Request, res: Response): Promise<void> {
|
||||||
|
const { classId, assignmentId, groupId, full } = getGroupParams(req);
|
||||||
|
|
||||||
|
const questions = await getGroupQuestions(classId, assignmentId, groupId, full);
|
||||||
|
|
||||||
|
res.json({ questions });
|
||||||
|
}
|
||||||
|
|
|
@ -62,9 +62,7 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
|
||||||
|
|
||||||
public async findAllByAssignment(assignment: Assignment): Promise<Question[]> {
|
public async findAllByAssignment(assignment: Assignment): Promise<Question[]> {
|
||||||
return this.find({
|
return this.find({
|
||||||
inGroup: {
|
inGroup: assignment.groups.getItems(),
|
||||||
$contained: assignment.groups,
|
|
||||||
},
|
|
||||||
learningObjectHruid: assignment.learningPathHruid,
|
learningObjectHruid: assignment.learningPathHruid,
|
||||||
learningObjectLanguage: assignment.learningPathLanguage,
|
learningObjectLanguage: assignment.learningPathLanguage,
|
||||||
});
|
});
|
||||||
|
@ -77,6 +75,13 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async findAllByGroup(inGroup: Group): Promise<Question[]> {
|
||||||
|
return this.findAll({
|
||||||
|
where: { inGroup },
|
||||||
|
orderBy: { timestamp: 'DESC' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up all questions for the given learning object which were asked as part of the given assignment.
|
* 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.
|
* When forStudentUsername is set, only the questions within the given user's group are shown.
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
deleteAssignmentHandler,
|
deleteAssignmentHandler,
|
||||||
getAllAssignmentsHandler,
|
getAllAssignmentsHandler,
|
||||||
getAssignmentHandler,
|
getAssignmentHandler,
|
||||||
|
getAssignmentQuestionsHandler,
|
||||||
getAssignmentsSubmissionsHandler,
|
getAssignmentsSubmissionsHandler,
|
||||||
putAssignmentHandler,
|
putAssignmentHandler,
|
||||||
} from '../controllers/assignments.js';
|
} from '../controllers/assignments.js';
|
||||||
|
@ -23,11 +24,7 @@ router.delete('/:id', deleteAssignmentHandler);
|
||||||
|
|
||||||
router.get('/:id/submissions', getAssignmentsSubmissionsHandler);
|
router.get('/:id/submissions', getAssignmentsSubmissionsHandler);
|
||||||
|
|
||||||
router.get('/:id/questions', (_req, res) => {
|
router.get('/:id/questions', getAssignmentQuestionsHandler);
|
||||||
res.json({
|
|
||||||
questions: ['0'],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.use('/:assignmentid/groups', groupRouter);
|
router.use('/:assignmentid/groups', groupRouter);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
deleteGroupHandler,
|
deleteGroupHandler,
|
||||||
getAllGroupsHandler,
|
getAllGroupsHandler,
|
||||||
getGroupHandler,
|
getGroupHandler,
|
||||||
|
getGroupQuestionsHandler,
|
||||||
getGroupSubmissionsHandler,
|
getGroupSubmissionsHandler,
|
||||||
putGroupHandler,
|
putGroupHandler,
|
||||||
} from '../controllers/groups.js';
|
} from '../controllers/groups.js';
|
||||||
|
@ -23,4 +24,6 @@ router.delete('/:groupid', deleteGroupHandler);
|
||||||
|
|
||||||
router.get('/:groupid/submissions', getGroupSubmissionsHandler);
|
router.get('/:groupid/submissions', getGroupSubmissionsHandler);
|
||||||
|
|
||||||
|
router.get('/:groupid/questions', getGroupQuestionsHandler);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { EntityDTO } from '@mikro-orm/core';
|
import { EntityDTO } from '@mikro-orm/core';
|
||||||
import { getGroupRepository, getSubmissionRepository } from '../data/repositories.js';
|
import { getGroupRepository, getQuestionRepository, getSubmissionRepository } from '../data/repositories.js';
|
||||||
import { Group } from '../entities/assignments/group.entity.js';
|
import { Group } from '../entities/assignments/group.entity.js';
|
||||||
import { mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js';
|
import { mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js';
|
||||||
import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js';
|
import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js';
|
||||||
|
@ -12,6 +12,8 @@ import { fetchClass } from './classes.js';
|
||||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||||
import { Student } from '../entities/users/student.entity.js';
|
import { Student } from '../entities/users/student.entity.js';
|
||||||
import { Class } from '../entities/classes/class.entity.js';
|
import { Class } from '../entities/classes/class.entity.js';
|
||||||
|
import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question';
|
||||||
|
import { mapToQuestionDTO, mapToQuestionDTOId } from '../interfaces/question.js';
|
||||||
|
|
||||||
async function assertMembersInClass(members: Student[], cls: Class): Promise<void> {
|
async function assertMembersInClass(members: Student[], cls: Class): Promise<void> {
|
||||||
if (!members.every((student) => cls.students.contains(student))) {
|
if (!members.every((student) => cls.students.contains(student))) {
|
||||||
|
@ -121,3 +123,21 @@ export async function getGroupSubmissions(
|
||||||
|
|
||||||
return submissions.map(mapToSubmissionDTOId);
|
return submissions.map(mapToSubmissionDTOId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getGroupQuestions(
|
||||||
|
classId: string,
|
||||||
|
assignmentNumber: number,
|
||||||
|
groupNumber: number,
|
||||||
|
full: boolean
|
||||||
|
): Promise<QuestionDTO[] | QuestionId[]> {
|
||||||
|
const group = await fetchGroup(classId, assignmentNumber, groupNumber);
|
||||||
|
|
||||||
|
const questionRepository = getQuestionRepository();
|
||||||
|
const questions = await questionRepository.findAllByGroup(group);
|
||||||
|
|
||||||
|
if (full) {
|
||||||
|
return questions.map(mapToQuestionDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return questions.map(mapToQuestionDTOId);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue