feat(frontend): Merge dev into feat/assignment
This commit is contained in:
		
						commit
						83f01830e3
					
				
					 132 changed files with 4916 additions and 2990 deletions
				
			
		
							
								
								
									
										39
									
								
								frontend/src/controllers/answers.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								frontend/src/controllers/answers.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| import type { AnswerData, AnswerDTO, AnswerId } from "@dwengo-1/common/interfaces/answer"; | ||||
| import { BaseController } from "@/controllers/base-controller.ts"; | ||||
| import type { QuestionId } from "@dwengo-1/common/interfaces/question"; | ||||
| 
 | ||||
| export interface AnswersResponse { | ||||
|     answers: AnswerDTO[] | AnswerId[]; | ||||
| } | ||||
| 
 | ||||
| export interface AnswerResponse { | ||||
|     answer: AnswerDTO; | ||||
| } | ||||
| 
 | ||||
| export class AnswerController extends BaseController { | ||||
|     constructor(questionId: QuestionId) { | ||||
|         this.loId = questionId.learningObjectIdentifier; | ||||
|         this.sequenceNumber = questionId.sequenceNumber; | ||||
|         super(`learningObject/${loId.hruid}/:${loId.version}/questions/${this.sequenceNumber}/answers`); | ||||
|     } | ||||
| 
 | ||||
|     async getAll(full = true): Promise<AnswersResponse> { | ||||
|         return this.get<AnswersResponse>("/", { lang: this.loId.lang, full }); | ||||
|     } | ||||
| 
 | ||||
|     async getBy(seq: number): Promise<AnswerResponse> { | ||||
|         return this.get<AnswerResponse>(`/${seq}`, { lang: this.loId.lang }); | ||||
|     } | ||||
| 
 | ||||
|     async create(answerData: AnswerData): Promise<AnswerResponse> { | ||||
|         return this.post<AnswerResponse>("/", answerData, { lang: this.loId.lang }); | ||||
|     } | ||||
| 
 | ||||
|     async remove(seq: number): Promise<AnswerResponse> { | ||||
|         return this.delete<AnswerResponse>(`/${seq}`, { lang: this.loId.lang }); | ||||
|     } | ||||
| 
 | ||||
|     async update(seq: number, answerData: AnswerData): Promise<AnswerResponse> { | ||||
|         return this.put<AnswerResponse>(`/${seq}`, answerData, { lang: this.loId.lang }); | ||||
|     } | ||||
| } | ||||
|  | @ -33,6 +33,10 @@ export class AssignmentController extends BaseController { | |||
|         return this.delete<AssignmentResponse>(`/${num}`); | ||||
|     } | ||||
| 
 | ||||
|     async updateAssignment(num: number, data: Partial<AssignmentDTO>): Promise<AssignmentResponse> { | ||||
|         return this.put<AssignmentResponse>(`/${num}`, data); | ||||
|     } | ||||
| 
 | ||||
|     async getSubmissions(assignmentNumber: number, full = true): Promise<SubmissionsResponse> { | ||||
|         return this.get<SubmissionsResponse>(`/${assignmentNumber}/submissions`, { full }); | ||||
|     } | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ export abstract class BaseController { | |||
|     } | ||||
| 
 | ||||
|     private static assertSuccessResponse(response: AxiosResponse<unknown, unknown>): void { | ||||
|         if (response.status / 100 !== 2) { | ||||
|         if (response.status < 200 || response.status >= 300) { | ||||
|             throw new HttpErrorResponseException(response); | ||||
|         } | ||||
|     } | ||||
|  | @ -21,20 +21,20 @@ export abstract class BaseController { | |||
|         return response.data; | ||||
|     } | ||||
| 
 | ||||
|     protected async post<T>(path: string, body: unknown): Promise<T> { | ||||
|         const response = await apiClient.post<T>(this.absolutePathFor(path), body); | ||||
|     protected async post<T>(path: string, body: unknown, queryParams?: QueryParams): Promise<T> { | ||||
|         const response = await apiClient.post<T>(this.absolutePathFor(path), body, { params: queryParams }); | ||||
|         BaseController.assertSuccessResponse(response); | ||||
|         return response.data; | ||||
|     } | ||||
| 
 | ||||
|     protected async delete<T>(path: string): Promise<T> { | ||||
|         const response = await apiClient.delete<T>(this.absolutePathFor(path)); | ||||
|     protected async delete<T>(path: string, queryParams?: QueryParams): Promise<T> { | ||||
|         const response = await apiClient.delete<T>(this.absolutePathFor(path), { params: queryParams }); | ||||
|         BaseController.assertSuccessResponse(response); | ||||
|         return response.data; | ||||
|     } | ||||
| 
 | ||||
|     protected async put<T>(path: string, body: unknown): Promise<T> { | ||||
|         const response = await apiClient.put<T>(this.absolutePathFor(path), body); | ||||
|     protected async put<T>(path: string, body: unknown, queryParams?: QueryParams): Promise<T> { | ||||
|         const response = await apiClient.put<T>(this.absolutePathFor(path), body, { params: queryParams }); | ||||
|         BaseController.assertSuccessResponse(response); | ||||
|         return response.data; | ||||
|     } | ||||
|  |  | |||
|  | @ -2,7 +2,8 @@ import { BaseController } from "./base-controller"; | |||
| import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; | ||||
| import type { StudentsResponse } from "./students"; | ||||
| import type { AssignmentsResponse } from "./assignments"; | ||||
| import type { TeacherInvitationDTO } from "@dwengo-1/common/interfaces/teacher-invitation"; | ||||
| import type { TeachersResponse } from "@/controllers/teachers.ts"; | ||||
| import type { TeacherInvitationsResponse } from "@/controllers/teacher-invitations.ts"; | ||||
| 
 | ||||
| export interface ClassesResponse { | ||||
|     classes: ClassDTO[] | string[]; | ||||
|  | @ -12,14 +13,6 @@ export interface ClassResponse { | |||
|     class: ClassDTO; | ||||
| } | ||||
| 
 | ||||
| export interface TeacherInvitationsResponse { | ||||
|     invites: TeacherInvitationDTO[]; | ||||
| } | ||||
| 
 | ||||
| export interface TeacherInvitationResponse { | ||||
|     invite: TeacherInvitationDTO; | ||||
| } | ||||
| 
 | ||||
| export class ClassController extends BaseController { | ||||
|     constructor() { | ||||
|         super("class"); | ||||
|  | @ -41,10 +34,34 @@ export class ClassController extends BaseController { | |||
|         return this.delete<ClassResponse>(`/${id}`); | ||||
|     } | ||||
| 
 | ||||
|     async updateClass(id: string, data: Partial<ClassDTO>): Promise<ClassResponse> { | ||||
|         return this.put<ClassResponse>(`/${id}`, data); | ||||
|     } | ||||
| 
 | ||||
|     async getStudents(id: string, full = true): Promise<StudentsResponse> { | ||||
|         return this.get<StudentsResponse>(`/${id}/students`, { full }); | ||||
|     } | ||||
| 
 | ||||
|     async addStudent(id: string, username: string): Promise<ClassResponse> { | ||||
|         return this.post<ClassResponse>(`/${id}/students`, { username }); | ||||
|     } | ||||
| 
 | ||||
|     async deleteStudent(id: string, username: string): Promise<ClassResponse> { | ||||
|         return this.delete<ClassResponse>(`/${id}/students/${username}`); | ||||
|     } | ||||
| 
 | ||||
|     async getTeachers(id: string, full = true): Promise<TeachersResponse> { | ||||
|         return this.get<TeachersResponse>(`/${id}/teachers`, { full }); | ||||
|     } | ||||
| 
 | ||||
|     async addTeacher(id: string, username: string): Promise<ClassResponse> { | ||||
|         return this.post<ClassResponse>(`/${id}/teachers`, { username }); | ||||
|     } | ||||
| 
 | ||||
|     async deleteTeacher(id: string, username: string): Promise<ClassResponse> { | ||||
|         return this.delete<ClassResponse>(`/${id}/teachers/${username}`); | ||||
|     } | ||||
| 
 | ||||
|     async getTeacherInvitations(id: string, full = true): Promise<TeacherInvitationsResponse> { | ||||
|         return this.get<TeacherInvitationsResponse>(`/${id}/teacher-invitations`, { full }); | ||||
|     } | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { ThemeController } from "@/controllers/themes.ts"; | ||||
| import { LearningObjectController } from "@/controllers/learning-objects.ts"; | ||||
| import { LearningPathController } from "@/controllers/learning-paths.ts"; | ||||
| import {ClassController} from "@/controllers/classes.ts"; | ||||
| import { ClassController } from "@/controllers/classes.ts"; | ||||
| 
 | ||||
| export function controllerGetter<T>(factory: new () => T): () => T { | ||||
|     let instance: T | undefined; | ||||
|  |  | |||
|  | @ -32,11 +32,15 @@ export class GroupController extends BaseController { | |||
|         return this.delete<GroupResponse>(`/${num}`); | ||||
|     } | ||||
| 
 | ||||
|     async getSubmissions(groupNumber: number, full = true): Promise<SubmissionsResponse> { | ||||
|         return this.get<SubmissionsResponse>(`/${groupNumber}/submissions`, { full }); | ||||
|     async updateGroup(num: number, data: Partial<GroupDTO>): Promise<GroupResponse> { | ||||
|         return this.put<GroupResponse>(`/${num}`, data); | ||||
|     } | ||||
| 
 | ||||
|     async getQuestions(groupNumber: number, full = true): Promise<QuestionsResponse> { | ||||
|         return this.get<QuestionsResponse>(`/${groupNumber}/questions`, { full }); | ||||
|     async getSubmissions(num: number, full = true): Promise<SubmissionsResponse> { | ||||
|         return this.get<SubmissionsResponse>(`/${num}/submissions`, { full }); | ||||
|     } | ||||
| 
 | ||||
|     async getQuestions(num: number, full = true): Promise<QuestionsResponse> { | ||||
|         return this.get<QuestionsResponse>(`/${num}/questions`, { full }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,38 @@ | |||
| import type { QuestionDTO, QuestionId } from "@dwengo-1/common/interfaces/question"; | ||||
| import type { QuestionData, QuestionDTO, QuestionId } from "@dwengo-1/common/interfaces/question"; | ||||
| import { BaseController } from "@/controllers/base-controller.ts"; | ||||
| import type { LearningObjectIdentifierDTO } from "@dwengo-1/common/interfaces/learning-content"; | ||||
| 
 | ||||
| export interface QuestionsResponse { | ||||
|     questions: QuestionDTO[] | QuestionId[]; | ||||
| } | ||||
| 
 | ||||
| export interface QuestionResponse { | ||||
|     question: QuestionDTO; | ||||
| } | ||||
| 
 | ||||
| export class QuestionController extends BaseController { | ||||
|     constructor(loId: LearningObjectIdentifierDTO) { | ||||
|         this.loId = loId; | ||||
|         super(`learningObject/${loId.hruid}/:${loId.version}/questions`); | ||||
|     } | ||||
| 
 | ||||
|     async getAll(full = true): Promise<QuestionsResponse> { | ||||
|         return this.get<QuestionsResponse>("/", { lang: this.loId.lang, full }); | ||||
|     } | ||||
| 
 | ||||
|     async getBy(sequenceNumber: number): Promise<QuestionResponse> { | ||||
|         return this.get<QuestionResponse>(`/${sequenceNumber}`, { lang: this.loId.lang }); | ||||
|     } | ||||
| 
 | ||||
|     async create(questionData: QuestionData): Promise<QuestionResponse> { | ||||
|         return this.post<QuestionResponse>("/", questionData, { lang: this.loId.lang }); | ||||
|     } | ||||
| 
 | ||||
|     async remove(sequenceNumber: number): Promise<QuestionResponse> { | ||||
|         return this.delete<QuestionResponse>(`/${sequenceNumber}`, { lang: this.loId.lang }); | ||||
|     } | ||||
| 
 | ||||
|     async update(sequenceNumber: number, questionData: QuestionData): Promise<QuestionResponse> { | ||||
|         return this.put<QuestionResponse>(`/${sequenceNumber}`, questionData, { lang: this.loId.lang }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -70,7 +70,7 @@ export class StudentController extends BaseController { | |||
|     } | ||||
| 
 | ||||
|     async createJoinRequest(username: string, classId: string): Promise<JoinRequestResponse> { | ||||
|         return this.post<JoinRequestResponse>(`/${username}/joinRequests}`, classId); | ||||
|         return this.post<JoinRequestResponse>(`/${username}/joinRequests`, { classId }); | ||||
|     } | ||||
| 
 | ||||
|     async deleteJoinRequest(username: string, classId: string): Promise<JoinRequestResponse> { | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ export interface SubmissionResponse { | |||
| 
 | ||||
| export class SubmissionController extends BaseController { | ||||
|     constructor(classid: string, assignmentNumber: number, groupNumber: number) { | ||||
|         super(`class/${classid}/assignments/${assignmentNumber}/groups/${groupNumber}`); | ||||
|         super(`class/${classid}/assignments/${assignmentNumber}/groups/${groupNumber}/submissions`); | ||||
|     } | ||||
| 
 | ||||
|     async getAll(full = true): Promise<SubmissionsResponse> { | ||||
|  | @ -22,7 +22,7 @@ export class SubmissionController extends BaseController { | |||
|         return this.get<SubmissionResponse>(`/${submissionNumber}`); | ||||
|     } | ||||
| 
 | ||||
|     async createSubmission(data: unknown): Promise<SubmissionResponse> { | ||||
|     async createSubmission(data: SubmissionDTO): Promise<SubmissionResponse> { | ||||
|         return this.post<SubmissionResponse>(`/`, data); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										36
									
								
								frontend/src/controllers/teacher-invitations.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								frontend/src/controllers/teacher-invitations.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| import { BaseController } from "@/controllers/base-controller.ts"; | ||||
| import type { TeacherInvitationData, TeacherInvitationDTO } from "@dwengo-1/common/interfaces/teacher-invitation"; | ||||
| 
 | ||||
| export interface TeacherInvitationsResponse { | ||||
|     invitations: TeacherInvitationDTO[]; | ||||
| } | ||||
| 
 | ||||
| export interface TeacherInvitationResponse { | ||||
|     invitation: TeacherInvitationDTO; | ||||
| } | ||||
| 
 | ||||
| export class TeacherInvitationController extends BaseController { | ||||
|     constructor() { | ||||
|         super("teachers/invitations"); | ||||
|     } | ||||
| 
 | ||||
|     async getAll(username: string, sent: boolean): Promise<TeacherInvitationsResponse> { | ||||
|         return this.get<TeacherInvitationsResponse>(`/${username}`, { sent }); | ||||
|     } | ||||
| 
 | ||||
|     async getBy(data: TeacherInvitationData): Promise<TeacherInvitationResponse> { | ||||
|         return this.get<TeacherInvitationResponse>(`/${data.sender}/${data.receiver}/${data.class}`); | ||||
|     } | ||||
| 
 | ||||
|     async create(data: TeacherInvitationData): Promise<TeacherInvitationResponse> { | ||||
|         return this.post<TeacherInvitationResponse>("/", data); | ||||
|     } | ||||
| 
 | ||||
|     async remove(data: TeacherInvitationData): Promise<TeacherInvitationResponse> { | ||||
|         return this.delete<TeacherInvitationResponse>(`/${data.sender}/${data.receiver}/${data.class}`); | ||||
|     } | ||||
| 
 | ||||
|     async respond(data: TeacherInvitationData): Promise<TeacherInvitationResponse> { | ||||
|         return this.put<TeacherInvitationResponse>("/", data); | ||||
|     } | ||||
| } | ||||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana