diff --git a/backend/src/controllers/submissions.ts b/backend/src/controllers/submissions.ts index a117d7bf..012636ea 100644 --- a/backend/src/controllers/submissions.ts +++ b/backend/src/controllers/submissions.ts @@ -62,6 +62,11 @@ export async function getAllSubmissionsHandler(req: Request, res: Response): Pro // TODO: gerald moet nog dingen toevoegen aan de databank voor dat dit gefinaliseerd kan worden export async function createSubmissionHandler(req: Request, res: Response): Promise { + const submitter = req.body.submitter; + const usernameSubmitter = req.body.submitter.username; + const group = req.body.group; + requireFields({ group, submitter, usernameSubmitter }); + const submissionDTO = req.body as SubmissionDTO; const submission = await createSubmission(submissionDTO); diff --git a/backend/src/controllers/teachers.ts b/backend/src/controllers/teachers.ts index c8063f80..6d8ab0bc 100644 --- a/backend/src/controllers/teachers.ts +++ b/backend/src/controllers/teachers.ts @@ -7,7 +7,6 @@ import { getJoinRequestsByClass, getStudentsByTeacher, getTeacher, - getTeacherQuestions, updateClassJoinRequestStatus, } from '../services/teachers.js'; import { requireFields } from './error-helper.js'; @@ -70,16 +69,6 @@ export async function getTeacherStudentHandler(req: Request, res: Response): Pro res.json({ students }); } -export async function getTeacherQuestionHandler(req: Request, res: Response): Promise { - const username = req.params.username; - const full = req.query.full === 'true'; - requireFields({ username }); - - const questions = await getTeacherQuestions(username, full); - - res.json({ questions }); -} - export async function getStudentJoinRequestHandler(req: Request, res: Response): Promise { const classId = req.params.classId; requireFields({ classId }); diff --git a/backend/src/entities/assignments/assignment.entity.ts b/backend/src/entities/assignments/assignment.entity.ts index a12ffbac..88c3160f 100644 --- a/backend/src/entities/assignments/assignment.entity.ts +++ b/backend/src/entities/assignments/assignment.entity.ts @@ -26,6 +26,9 @@ export class Assignment { @Property({ type: 'string' }) learningPathHruid!: string; + @Property({ type: 'datetime', nullable: true }) + deadline?: Date; + @Enum({ items: () => Language, }) diff --git a/backend/src/interfaces/assignment.ts b/backend/src/interfaces/assignment.ts index 7c5a0909..2dc158d2 100644 --- a/backend/src/interfaces/assignment.ts +++ b/backend/src/interfaces/assignment.ts @@ -20,6 +20,7 @@ export function mapToAssignmentDTO(assignment: Assignment): AssignmentDTO { description: assignment.description, learningPath: assignment.learningPathHruid, language: assignment.learningPathLanguage, + deadline: assignment.deadline ?? new Date(), groups: assignment.groups.map((group) => mapToGroupDTO(group, assignment.within)), }; } @@ -31,6 +32,7 @@ export function mapToAssignment(assignmentData: AssignmentDTO, cls: Class): Assi description: assignmentData.description, learningPathHruid: assignmentData.learningPath, learningPathLanguage: languageMap[assignmentData.language], + deadline: assignmentData.deadline, groups: [], }); } diff --git a/backend/src/routes/teachers.ts b/backend/src/routes/teachers.ts index 44d3064b..b858102d 100644 --- a/backend/src/routes/teachers.ts +++ b/backend/src/routes/teachers.ts @@ -6,7 +6,6 @@ import { getStudentJoinRequestHandler, getTeacherClassHandler, getTeacherHandler, - getTeacherQuestionHandler, getTeacherStudentHandler, updateStudentJoinRequestHandler, } from '../controllers/teachers.js'; @@ -27,8 +26,6 @@ router.get('/:username/classes', getTeacherClassHandler); router.get('/:username/students', getTeacherStudentHandler); -router.get('/:username/questions', getTeacherQuestionHandler); - router.get('/:username/joinRequests/:classId', getStudentJoinRequestHandler); router.put('/:username/joinRequests/:classId/:studentUsername', updateStudentJoinRequestHandler); diff --git a/backend/src/services/students.ts b/backend/src/services/students.ts index 77ec6648..809b23e4 100644 --- a/backend/src/services/students.ts +++ b/backend/src/services/students.ts @@ -42,7 +42,7 @@ export async function fetchStudent(username: string): Promise { const user = await studentRepository.findByUsername(username); if (!user) { - throw new NotFoundException('Student with username not found'); + throw new NotFoundException(`Student with username ${username} not found`); } return user; diff --git a/backend/src/services/teachers.ts b/backend/src/services/teachers.ts index 8857de99..2666be8c 100644 --- a/backend/src/services/teachers.ts +++ b/backend/src/services/teachers.ts @@ -1,12 +1,5 @@ -import { - getClassJoinRequestRepository, - getClassRepository, - getLearningObjectRepository, - getQuestionRepository, - getTeacherRepository, -} from '../data/repositories.js'; +import { getClassJoinRequestRepository, getClassRepository, getTeacherRepository } from '../data/repositories.js'; import { mapToClassDTO } from '../interfaces/class.js'; -import { mapToQuestionDTO, mapToQuestionDTOId } from '../interfaces/question.js'; import { mapToTeacher, mapToTeacherDTO } from '../interfaces/teacher.js'; import { Teacher } from '../entities/users/teacher.entity.js'; import { fetchStudent } from './students.js'; @@ -15,10 +8,6 @@ import { mapToStudentRequestDTO } from '../interfaces/student-request.js'; import { TeacherRepository } from '../data/users/teacher-repository.js'; import { ClassRepository } from '../data/classes/class-repository.js'; import { Class } from '../entities/classes/class.entity.js'; -import { LearningObjectRepository } from '../data/content/learning-object-repository.js'; -import { LearningObject } from '../entities/content/learning-object.entity.js'; -import { QuestionRepository } from '../data/questions/question-repository.js'; -import { Question } from '../entities/questions/question.entity.js'; import { ClassJoinRequestRepository } from '../data/classes/class-join-request-repository.js'; import { Student } from '../entities/users/student.entity.js'; import { NotFoundException } from '../exceptions/not-found-exception.js'; @@ -26,7 +15,6 @@ import { addClassStudent, fetchClass, getClassStudentsDTO } from './classes.js'; import { TeacherDTO } from '@dwengo-1/common/interfaces/teacher'; import { ClassDTO } from '@dwengo-1/common/interfaces/class'; import { StudentDTO } from '@dwengo-1/common/interfaces/student'; -import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; import { ConflictException } from '../exceptions/conflict-exception.js'; @@ -119,28 +107,6 @@ export async function getStudentsByTeacher(username: string, full: boolean): Pro return students.map((student) => student.username); } -export async function getTeacherQuestions(username: string, full: boolean): Promise { - const teacher: Teacher = await fetchTeacher(username); - - // Find all learning objects that this teacher manages - const learningObjectRepository: LearningObjectRepository = getLearningObjectRepository(); - const learningObjects: LearningObject[] = await learningObjectRepository.findAllByAdmin(teacher.username); - - if (!learningObjects || learningObjects.length === 0) { - return []; - } - - // Fetch all questions related to these learning objects - const questionRepository: QuestionRepository = getQuestionRepository(); - const questions: Question[] = await questionRepository.findAllByLearningObjects(learningObjects); - - if (full) { - return questions.map(mapToQuestionDTO); - } - - return questions.map(mapToQuestionDTOId); -} - export async function getJoinRequestsByClass(classId: string): Promise { const classRepository: ClassRepository = getClassRepository(); const cls: Class | null = await classRepository.findById(classId); diff --git a/backend/tests/controllers/assignments.test.ts b/backend/tests/controllers/assignments.test.ts new file mode 100644 index 00000000..88cac366 --- /dev/null +++ b/backend/tests/controllers/assignments.test.ts @@ -0,0 +1,76 @@ +import { setupTestApp } from '../setup-tests.js'; +import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; +import { Request, Response } from 'express'; +import { getAssignmentHandler, getAllAssignmentsHandler, getAssignmentsSubmissionsHandler } from '../../src/controllers/assignments.js'; +import { NotFoundException } from '../../src/exceptions/not-found-exception'; +import { getClass01 } from '../test_assets/classes/classes.testdata'; +import { getAssignment01 } from '../test_assets/assignments/assignments.testdata'; + +function createRequestObject( + classid: string, + assignmentid: string +): { + query: { full: string }; + params: { classid: string; id: string }; +} { + return { + params: { + classid: classid, + id: assignmentid, + }, + query: { + full: 'true', + }, + }; +} + +describe('Assignment controllers', () => { + let req: Partial; + let res: Partial; + + let jsonMock: Mock; + let statusMock: Mock; + + beforeAll(async () => { + await setupTestApp(); + }); + + beforeEach(async () => { + jsonMock = vi.fn(); + statusMock = vi.fn().mockReturnThis(); + + res = { + json: jsonMock, + status: statusMock, + }; + }); + + it('return error non-existing assignment', async () => { + req = createRequestObject('doesnotexist', '43000'); // Should not exist + + await expect(async () => getAssignmentHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return an assignment', async () => { + const assignment = getAssignment01(); + req = createRequestObject(assignment.within.classId as string, (assignment.id ?? 1).toString()); + + await getAssignmentHandler(req as Request, res as Response); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ assignment: expect.anything() })); + }); + + it('should return a list of assignments', async () => { + req = createRequestObject(getClass01().classId as string, 'irrelevant'); + + await getAllAssignmentsHandler(req as Request, res as Response); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ assignments: expect.anything() })); + }); + + it('should return a list of submissions for an assignment', async () => { + const assignment = getAssignment01(); + req = createRequestObject(assignment.within.classId as string, (assignment.id ?? 1).toString()); + + await getAssignmentsSubmissionsHandler(req as Request, res as Response); + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ submissions: expect.anything() })); + }); +}); diff --git a/backend/tests/controllers/classes.test.ts b/backend/tests/controllers/classes.test.ts index ab941773..d9614a3b 100644 --- a/backend/tests/controllers/classes.test.ts +++ b/backend/tests/controllers/classes.test.ts @@ -1,8 +1,17 @@ import { setupTestApp } from '../setup-tests.js'; import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; +import { + createClassHandler, + deleteClassHandler, + getAllClassesHandler, + getClassHandler, + getClassStudentsHandler, + getTeacherInvitationsHandler, +} from '../../src/controllers/classes.js'; import { Request, Response } from 'express'; -import { createClassHandler, deleteClassHandler } from '../../src/controllers/classes'; - +import { NotFoundException } from '../../src/exceptions/not-found-exception'; +import { BadRequestException } from '../../src/exceptions/bad-request-exception'; +import { getClass01 } from '../test_assets/classes/classes.testdata'; describe('Class controllers', () => { let req: Partial; let res: Partial; @@ -44,4 +53,71 @@ describe('Class controllers', () => { expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ class: expect.anything() })); }); + + it('Error class not found', async () => { + req = { + params: { id: 'doesnotexist' }, + }; + + await expect(async () => getClassHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('Error create a class without name', async () => { + req = { + body: {}, + }; + + await expect(async () => createClassHandler(req as Request, res as Response)).rejects.toThrow(BadRequestException); + }); + + it('return list of students', async () => { + req = { + params: { id: getClass01().classId as string }, + query: {}, + }; + + await getClassStudentsHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ students: expect.anything() })); + }); + + it('Error students on a non-existent class', async () => { + req = { + params: { id: 'doesnotexist' }, + query: {}, + }; + + await expect(async () => getClassStudentsHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return 200 and a list of teacher-invitations', async () => { + const classId = getClass01().classId as string; + req = { + params: { id: classId }, + query: {}, + }; + + await getTeacherInvitationsHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ invitations: expect.anything() })); + }); + + it('Error teacher-invitations on a non-existent class', async () => { + req = { + params: { id: 'doesnotexist' }, + query: {}, + }; + + await expect(async () => getTeacherInvitationsHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return a list of classes', async () => { + req = { + query: {}, + }; + + await getAllClassesHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ classes: expect.anything() })); + }); }); diff --git a/backend/tests/controllers/groups.test.ts b/backend/tests/controllers/groups.test.ts new file mode 100644 index 00000000..f9e35cea --- /dev/null +++ b/backend/tests/controllers/groups.test.ts @@ -0,0 +1,140 @@ +import { setupTestApp } from '../setup-tests.js'; +import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; +import { Request, Response } from 'express'; +import { + createGroupHandler, + deleteGroupHandler, + getAllGroupsHandler, + getGroupHandler, + getGroupSubmissionsHandler, +} from '../../src/controllers/groups.js'; +import { NotFoundException } from '../../src/exceptions/not-found-exception'; +import { getClass01 } from '../test_assets/classes/classes.testdata'; +import { getAssignment01, getAssignment02 } from '../test_assets/assignments/assignments.testdata'; +import { getTestGroup01 } from '../test_assets/assignments/groups.testdata'; + +function createRequestObject( + classid: string, + assignmentid: string, + groupNumber: string +): { + query: { full: string }; + params: { classid: string; groupid: string; assignmentid: string }; +} { + return { + params: { + classid: classid, + assignmentid: assignmentid, + groupid: groupNumber, + }, + query: { + full: 'true', + }, + }; +} + +describe('Group controllers', () => { + let req: Partial; + let res: Partial; + + let jsonMock: Mock; + let statusMock: Mock; + + beforeAll(async () => { + await setupTestApp(); + }); + + beforeEach(async () => { + jsonMock = vi.fn(); + statusMock = vi.fn().mockReturnThis(); + + res = { + json: jsonMock, + status: statusMock, + }; + }); + + it('Error not found on a non-existing group', async () => { + req = { + params: { + classid: 'id01', + assignmentid: '1', + groupid: '154981', // Should not exist + }, + query: {}, + }; + + await expect(async () => getGroupHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return 404 not found on a non-existing assignment', async () => { + req = { + params: { + classid: 'id01', + assignmentid: '1000', // Should not exist + groupid: '42000', // Should not exist + }, + query: {}, + }; + + await expect(async () => getGroupHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return 404 not found ont a non-existing class', async () => { + req = { + params: { + classid: 'doesnotexist', // Should not exist + assignmentid: '1000', // Should not exist + groupid: '42000', // Should not exist + }, + query: {}, + }; + + await expect(async () => getGroupHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return an existing group', async () => { + const group = getTestGroup01(); + const classId = getClass01().classId as string; + req = createRequestObject(classId, (group.assignment.id ?? 1).toString(), (group.groupNumber ?? 1).toString()); + + await getGroupHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ group: expect.anything() })); + }); + + it('Create and delete', async () => { + const assignment = getAssignment02(); + const classId = assignment.within.classId as string; + req = createRequestObject(classId, (assignment.id ?? 1).toString(), '1'); + req.body = { + members: ['Noordkaap', 'DireStraits'], + }; + + await createGroupHandler(req as Request, res as Response); + + await deleteGroupHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ group: expect.anything() })); + }); + + it('should return the submissions for a group', async () => { + const group = getTestGroup01(); + const classId = getClass01().classId as string; + req = createRequestObject(classId, (group.assignment.id ?? 1).toString(), (group.groupNumber ?? 1).toString()); + + await getGroupSubmissionsHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ submissions: expect.anything() })); + }); + + it('should return a list of groups for an assignment', async () => { + const assignment = getAssignment01(); + const classId = assignment.within.classId as string; + req = createRequestObject(classId, (assignment.id ?? 1).toString(), '1'); + + await getAllGroupsHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ groups: expect.anything() })); + }); +}); diff --git a/backend/tests/controllers/submissions.test.ts b/backend/tests/controllers/submissions.test.ts new file mode 100644 index 00000000..942b51f8 --- /dev/null +++ b/backend/tests/controllers/submissions.test.ts @@ -0,0 +1,61 @@ +import { setupTestApp } from '../setup-tests.js'; +import { describe, it, expect, beforeAll, beforeEach, vi, Mock } from 'vitest'; +import { getSubmissionHandler, getAllSubmissionsHandler } from '../../src/controllers/submissions.js'; +import { Request, Response } from 'express'; +import { NotFoundException } from '../../src/exceptions/not-found-exception'; +import { getClass02 } from '../test_assets/classes/classes.testdata'; + +function createRequestObject( + hruid: string, + submissionNumber: string +): { + query: { language: string; version: string }; + params: { hruid: string; id: string }; +} { + return { + params: { + hruid: hruid, + id: submissionNumber, + }, + query: { + language: 'en', + version: '1', + }, + }; +} + +describe('Submission controllers', () => { + let req: Partial; + let res: Partial; + + let jsonMock: Mock; + let statusMock: Mock; + + beforeAll(async () => { + await setupTestApp(); + }); + + beforeEach(async () => { + jsonMock = vi.fn(); + statusMock = vi.fn().mockReturnThis(); + + res = { + json: jsonMock, + status: statusMock, + }; + }); + + it('error submission is not found', async () => { + req = createRequestObject('id01', '1000000'); + + await expect(async () => getSubmissionHandler(req as Request, res as Response)).rejects.toThrow(NotFoundException); + }); + + it('should return a list of submissions for a learning object', async () => { + req = createRequestObject(getClass02().classId as string, 'irrelevant'); + + await getAllSubmissionsHandler(req as Request, res as Response); + + expect(jsonMock).toHaveBeenCalledWith(expect.objectContaining({ submissions: expect.anything() })); + }); +}); diff --git a/backend/tests/test_assets/assignments/assignments.testdata.ts b/backend/tests/test_assets/assignments/assignments.testdata.ts index 337ec98f..dc477828 100644 --- a/backend/tests/test_assets/assignments/assignments.testdata.ts +++ b/backend/tests/test_assets/assignments/assignments.testdata.ts @@ -6,13 +6,20 @@ import { testLearningPathWithConditions } from '../content/learning-paths.testda import { getClassWithTestleerlingAndTestleerkracht } from '../classes/classes.testdata'; export function makeTestAssignemnts(em: EntityManager, classes: Class[]): Assignment[] { + const futureDate = new Date(); + futureDate.setDate(futureDate.getDate() + 7); + const pastDate = new Date(); + pastDate.setDate(pastDate.getDate() - 7); + const today = new Date(); + today.setHours(23, 59); assignment01 = em.create(Assignment, { id: 21000, within: classes[0], title: 'dire straits', description: 'reading', - learningPathHruid: 'id02', + learningPathHruid: 'un_ai', learningPathLanguage: Language.English, + deadline: today, groups: [], }); @@ -23,6 +30,7 @@ export function makeTestAssignemnts(em: EntityManager, classes: Class[]): Assign description: 'reading', learningPathHruid: 'id01', learningPathLanguage: Language.English, + deadline: futureDate, groups: [], }); @@ -33,6 +41,7 @@ export function makeTestAssignemnts(em: EntityManager, classes: Class[]): Assign description: 'will be deleted', learningPathHruid: 'id02', learningPathLanguage: Language.English, + deadline: pastDate, groups: [], }); @@ -43,6 +52,7 @@ export function makeTestAssignemnts(em: EntityManager, classes: Class[]): Assign description: 'with a description', learningPathHruid: 'id01', learningPathLanguage: Language.English, + deadline: pastDate, groups: [], }); @@ -53,6 +63,7 @@ export function makeTestAssignemnts(em: EntityManager, classes: Class[]): Assign description: 'You have to do the testing learning path with a condition.', learningPathHruid: testLearningPathWithConditions.hruid, learningPathLanguage: testLearningPathWithConditions.language as Language, + deadline: futureDate, groups: [], }); diff --git a/common/src/interfaces/assignment.ts b/common/src/interfaces/assignment.ts index fb7dfbf0..677221f1 100644 --- a/common/src/interfaces/assignment.ts +++ b/common/src/interfaces/assignment.ts @@ -7,6 +7,7 @@ export interface AssignmentDTO { description: string; learningPath: string; language: string; + deadline: Date; groups: GroupDTO[] | string[][]; } diff --git a/frontend/src/assets/common.css b/frontend/src/assets/common.css new file mode 100644 index 00000000..bcc5d39f --- /dev/null +++ b/frontend/src/assets/common.css @@ -0,0 +1,54 @@ +.h1 { + color: #0e6942; + text-transform: uppercase; + font-weight: bolder; + font-size: 50px; + padding-left: 1%; +} + +.empty-message { + text-align: center; + font-size: 18px; +} + +.header { + font-weight: bold !important; + background-color: #0e6942; + color: white; + padding: 10px; +} + +.table thead th:first-child { + border-top-left-radius: 10px; +} + +.table thead th:last-child { + border-top-right-radius: 10px; +} + +.table tbody tr:nth-child(odd) { + background-color: white; +} + +.table tbody tr:nth-child(even) { + background-color: #f6faf2; +} + +.table td, +.table th { + border-bottom: 1px solid #0e6942; + border-top: 1px solid #0e6942; +} + +.table { + width: 90%; + padding-top: 10px; + border-collapse: collapse; +} + +@media screen and (max-width: 850px) { + .h1 { + text-align: center; + padding-left: 0; + } +} diff --git a/frontend/src/components/BrowseThemes.vue b/frontend/src/components/BrowseThemes.vue index 58cca6ac..cfebe419 100644 --- a/frontend/src/components/BrowseThemes.vue +++ b/frontend/src/components/BrowseThemes.vue @@ -60,6 +60,22 @@ import authService from "@/services/auth/auth-service"; + + + - - - - + diff --git a/frontend/src/components/assignments/DeadlineSelector.vue b/frontend/src/components/assignments/DeadlineSelector.vue index 9295eec0..304c544c 100644 --- a/frontend/src/components/assignments/DeadlineSelector.vue +++ b/frontend/src/components/assignments/DeadlineSelector.vue @@ -1,49 +1,30 @@ - - diff --git a/frontend/src/controllers/teachers.ts b/frontend/src/controllers/teachers.ts index a97cf11f..a7adce18 100644 --- a/frontend/src/controllers/teachers.ts +++ b/frontend/src/controllers/teachers.ts @@ -1,6 +1,5 @@ import { BaseController } from "@/controllers/base-controller.ts"; import type { JoinRequestResponse, JoinRequestsResponse, StudentsResponse } from "@/controllers/students.ts"; -import type { QuestionsResponse } from "@/controllers/questions.ts"; import type { ClassesResponse } from "@/controllers/classes.ts"; import type { TeacherDTO } from "@dwengo-1/common/interfaces/teacher"; @@ -40,10 +39,6 @@ export class TeacherController extends BaseController { return this.get(`/${username}/students`, { full }); } - async getQuestions(username: string, full = false): Promise { - return this.get(`/${username}/questions`, { full }); - } - async getStudentJoinRequests(username: string, classId: string): Promise { return this.get(`/${username}/joinRequests/${classId}`); } diff --git a/frontend/src/i18n/locale/de.json b/frontend/src/i18n/locale/de.json index 5549db93..b2c03520 100644 --- a/frontend/src/i18n/locale/de.json +++ b/frontend/src/i18n/locale/de.json @@ -21,6 +21,7 @@ "JoinClassExplanation": "Geben Sie den Code ein, den Ihnen die Lehrkraft mitgeteilt hat, um der Klasse beizutreten.", "invalidFormat": "Ungültiges Format", "submitCode": "senden", + "submit": "senden", "members": "Mitglieder", "themes": "Themen", "choose-theme": "Wählen Sie ein Thema", @@ -68,10 +69,10 @@ "pick-class": "Wählen Sie eine klasse", "choose-students": "Studenten auswählen", "create-group": "Gruppe erstellen", - "class": "klasse", + "class": "Klasse", "delete": "löschen", "view-assignment": "Auftrag anzeigen", - "code": "code", + "code": "Code", "invitations": "Einladungen", "createClass": "Klasse erstellen", "createClassInstructions": "Geben Sie einen Namen für Ihre Klasse ein und klicken Sie auf „Erstellen“. Es erscheint ein Fenster mit einem Code, den Sie kopieren können. Geben Sie diesen Code an Ihre Schüler weiter und sie können Ihrer Klasse beitreten.", @@ -83,7 +84,7 @@ "onlyUse": "nur Buchstaben, Zahlen, Bindestriche (-) und Unterstriche (_) verwenden", "close": "schließen", "copied": "kopiert!", - "accept": "akzeptieren", + "accept": "Akzeptieren", "deny": "ablehnen", "sent": "sent", "failed": "fehlgeschlagen", @@ -110,7 +111,7 @@ "remove": "entfernen", "students": "Studenten", "classJoinRequests": "Beitrittsanfragen", - "reject": "ablehnen", + "reject": "Ablehnen", "areusure": "Sind Sie sicher?", "yes": "ja", "teachers": "Lehrer", @@ -122,6 +123,19 @@ "assignmentIndicator": "AUFGABE", "searchAllLearningPathsTitle": "Alle Lernpfade durchsuchen", "searchAllLearningPathsDescription": "Nicht gefunden, was Sie gesucht haben? Klicken Sie hier, um unsere gesamte Lernpfad-Datenbank zu durchsuchen.", + "no-students-found": "Diese Klasse hat keine Schüler.", + "no-invitations-found": "Sie haben keine ausstehenden Einladungen.", + "no-join-requests-found": "Es gibt keine ausstehenden Beitrittsanfragen für diese Klasse.", + "no-classes-found": "Sie sind noch keinem Kurs beigetreten.", + "classCreated": "Klasse erstellt!", + "success": "Erfolg", + "submitted": "eingereicht", + "see-submission": "Einsendung anzeigen", + "view-submissions": "Einsendungen anzeigen", + "valid-username": "Bitte geben Sie einen gültigen Benutzernamen ein", + "creationFailed": "Erstellung fehlgeschlagen, bitte versuchen Sie es erneut", + "no-assignments": "Derzeit gibt es keine Zuweisungen.", + "deadline": "deadline", "learningObjects": "Lernobjekte", "learningPaths": "Lernpfade", "hruid": "HRUID", diff --git a/frontend/src/i18n/locale/en.json b/frontend/src/i18n/locale/en.json index eb674173..5ed93799 100644 --- a/frontend/src/i18n/locale/en.json +++ b/frontend/src/i18n/locale/en.json @@ -33,6 +33,7 @@ "JoinClassExplanation": "Enter the code the teacher has given you to join the class.", "invalidFormat": "Invalid format.", "submitCode": "submit", + "submit": "submit", "members": "Members", "themes": "Themes", "choose-theme": "Select a theme", @@ -68,21 +69,21 @@ "pick-class": "Pick a class", "choose-students": "Select students", "create-group": "Create group", - "class": "class", + "class": "Class", "delete": "delete", "view-assignment": "View assignment", - "code": "code", - "invitations": "invitations", - "createClass": "create class", + "code": "Code", + "invitations": "Invitations", + "createClass": "Create class", "classname": "classname", "EnterNameOfClass": "Enter a classname.", "create": "create", - "sender": "sender", + "sender": "Sender", "nameIsMandatory": "classname is mandatory", "onlyUse": "only use letters, numbers, dashes (-) and underscores (_)", "close": "close", "copied": "copied!", - "accept": "accept", + "accept": "Accept", "deny": "deny", "createClassInstructions": "Enter a name for your class and click on create. A window will appear with a code that you can copy. Give this code to your students and they will be able to join.", "sent": "sent", @@ -108,12 +109,12 @@ "progress": "Progress", "created": "created", "remove": "remove", - "students": "students", - "classJoinRequests": "join requests", - "reject": "reject", + "students": "Students", + "classJoinRequests": "Join requests", + "reject": "Reject", "areusure": "Are you sure?", "yes": "yes", - "teachers": "teachers", + "teachers": "Teachers", "accepted": "accepted", "rejected": "rejected", "enterUsername": "enter the username of the teacher you would like to invite", @@ -122,6 +123,19 @@ "assignmentIndicator": "ASSIGNMENT", "searchAllLearningPathsTitle": "Search all learning paths", "searchAllLearningPathsDescription": "You didn't find what you were looking for? Click here to search our whole database of available learning paths.", + "no-students-found": "This class has no students.", + "no-invitations-found": "You have no pending invitations.", + "no-join-requests-found": "There are no pending join requests for this class.", + "no-classes-found": "You are not yet part of a class.", + "classCreated": "class created!", + "success": "success", + "submitted": "submitted", + "see-submission": "view submission", + "view-submissions": "view submissions", + "valid-username": "please enter a valid username", + "creationFailed": "creation failed, please try again", + "no-assignments": "There are currently no assignments.", + "deadline": "deadline", "learningObjects": "Learning objects", "learningPaths": "Learning paths", "hruid": "HRUID", diff --git a/frontend/src/i18n/locale/fr.json b/frontend/src/i18n/locale/fr.json index 3cfb83dd..fd4840fc 100644 --- a/frontend/src/i18n/locale/fr.json +++ b/frontend/src/i18n/locale/fr.json @@ -33,6 +33,7 @@ "JoinClassExplanation": "Entrez le code que l'enseignant vous a donné pour rejoindre la classe.", "invalidFormat": "Format non valide.", "submitCode": "envoyer", + "submit": "envoyer", "members": "Membres", "themes": "Thèmes", "choose-theme": "Choisis un thème", @@ -68,22 +69,22 @@ "pick-class": "Choisissez une classe", "choose-students": "Sélectionnez des élèves", "create-group": "Créer un groupe", - "class": "classe", + "class": "Classe", "delete": "supprimer", "view-assignment": "Voir le travail", - "code": "code", - "invitations": "invitations", - "createClass": "créer une classe", + "code": "Code", + "invitations": "Invitations", + "createClass": "Créer une classe", "createClassInstructions": "Entrez un nom pour votre classe et cliquez sur créer. Une fenêtre apparaît avec un code que vous pouvez copier. Donnez ce code à vos élèves et ils pourront rejoindre votre classe.", "classname": "nom de classe", "EnterNameOfClass": "saisir un nom de classe.", "create": "créer", - "sender": "expéditeur", + "sender": "Expéditeur", "nameIsMandatory": "le nom de classe est obligatoire", "onlyUse": "n'utiliser que des lettres, des chiffres, des tirets (-) et des traits de soulignement (_)", "close": "fermer", "copied": "copié!", - "accept": "accepter", + "accept": "Accepter", "deny": "refuser", "sent": "envoyé", "failed": "échoué", @@ -108,12 +109,13 @@ "submission": "Soumission", "progress": "Progrès", "remove": "supprimer", - "students": "étudiants", - "classJoinRequests": "demandes d'adhésion", - "reject": "rejeter", + "students": "Étudiants", + + "classJoinRequests": "Demandes d'adhésion", + "reject": "Rejeter", "areusure": "Êtes-vous sûr?", "yes": "oui", - "teachers": "enseignants", + "teachers": "Enseignants", "accepted": "acceptée", "rejected": "rejetée", "enterUsername": "entrez le nom d'utilisateur de l'enseignant que vous souhaitez inviter", @@ -122,6 +124,19 @@ "assignmentIndicator": "DEVOIR", "searchAllLearningPathsTitle": "Rechercher tous les parcours d'apprentissage", "searchAllLearningPathsDescription": "Vous n'avez pas trouvé ce que vous cherchiez ? Cliquez ici pour rechercher dans toute notre base de données de parcours d'apprentissage disponibles.", + "no-students-found": "Cette classe n'a pas d'élèves.", + "no-invitations-found": "Vous n'avez aucune invitation en attente.", + "no-join-requests-found": "Il n'y a aucune demande d'adhésion en attente pour cette classe.", + "no-classes-found": "Vous ne faites pas encore partie d'une classe.", + "classCreated": "Classe créée !", + "success": "succès", + "submitted": "soumis", + "see-submission": "voir la soumission", + "view-submissions": "voir les soumissions", + "valid-username": "veuillez entrer un nom d'utilisateur valide", + "creationFailed": "échec de la création, veuillez réessayer", + "no-assignments": "Il n'y a actuellement aucun travail.", + "deadline": "délai", "learningObjects": "Objets d’apprentissage", "learningPaths": "Parcours d’apprentissage", "hruid": "HRUID", diff --git a/frontend/src/i18n/locale/nl.json b/frontend/src/i18n/locale/nl.json index 72012331..b12bbf77 100644 --- a/frontend/src/i18n/locale/nl.json +++ b/frontend/src/i18n/locale/nl.json @@ -33,6 +33,7 @@ "JoinClassExplanation": "Voer de code in die je van de docent hebt gekregen om lid te worden van de klas.", "invalidFormat": "Ongeldig formaat.", "submitCode": "verzenden", + "submit": "verzenden", "members": "Leden", "themes": "Lesthema's", "choose-theme": "Kies een thema", @@ -68,22 +69,22 @@ "pick-class": "Kies een klas", "choose-students": "Studenten selecteren", "create-group": "Groep aanmaken", - "class": "klas", + "class": "Klas", "delete": "verwijderen", "view-assignment": "Opdracht bekijken", - "code": "code", - "invitations": "uitnodigingen", - "createClass": "klas aanmaken", + "code": "Code", + "invitations": "Uitnodigingen", + "createClass": "Klas aanmaken", "createClassInstructions": "Voer een naam in voor je klas en klik op create. Er verschijnt een venster met een code die je kunt kopiëren. Geef deze code aan je leerlingen en ze kunnen deelnemen aan je klas.", "classname": "klasnaam", "EnterNameOfClass": "Geef een klasnaam op.", "create": "aanmaken", - "sender": "afzender", + "sender": "Afzender", "nameIsMandatory": "klasnaam is verplicht", "onlyUse": "gebruik enkel letters, cijfers, dashes (-) en underscores (_)", "close": "sluiten", "copied": "gekopieerd!", - "accept": "accepteren", + "accept": "Accepteren", "deny": "weigeren", "sent": "verzonden", "failed": "mislukt", @@ -108,12 +109,12 @@ "submission": "Indiening", "progress": "Vooruitgang", "remove": "verwijder", - "students": "studenten", - "classJoinRequests": "deelname verzoeken", - "reject": "weiger", + "students": "Studenten", + "classJoinRequests": "Deelname verzoeken", + "reject": "Weiger", "areusure": "Bent u zeker?", "yes": "ja", - "teachers": "leerkrachten", + "teachers": "Leerkrachten", "accepted": "geaccepteerd", "rejected": "geweigerd", "enterUsername": "vul de gebruikersnaam van de leerkracht die je wilt uitnodigen in", @@ -122,6 +123,19 @@ "assignmentIndicator": "OPDRACHT", "searchAllLearningPathsTitle": "Alle leerpaden doorzoeken", "searchAllLearningPathsDescription": "Niet gevonden waar je naar op zoek was? Klik hier om onze volledige databank van beschikbare leerpaden te doorzoeken.", + "no-students-found": "Deze klas heeft geen leerlingen.", + "no-invitations-found": "U heeft geen openstaande uitnodigingen.", + "no-join-requests-found": "Er zijn geen openstaande verzoeken om lid te worden van deze klas.", + "no-classes-found": "U maakt nog geen deel uit van een klas.", + "classCreated": "Klas aangemaakt!", + "success": "succes", + "submitted": "ingediend", + "see-submission": "inzending bekijken", + "view-submissions": "inzendingen bekijken", + "valid-username": "voer een geldige gebruikersnaam in", + "creationFailed": "aanmaak mislukt, probeer het opnieuw", + "no-assignments": "Er zijn momenteel geen opdrachten.", + "deadline": "deadline", "learningObjects": "Leerobjecten", "learningPaths": "Leerpaden", "hruid": "HRUID", diff --git a/frontend/src/queries/teachers.ts b/frontend/src/queries/teachers.ts index 59da84f4..ed13f630 100644 --- a/frontend/src/queries/teachers.ts +++ b/frontend/src/queries/teachers.ts @@ -10,7 +10,6 @@ import { import { TeacherController, type TeacherResponse, type TeachersResponse } from "@/controllers/teachers.ts"; import type { ClassesResponse } from "@/controllers/classes.ts"; import type { JoinRequestResponse, JoinRequestsResponse, StudentsResponse } from "@/controllers/students.ts"; -import type { QuestionsResponse } from "@/controllers/questions.ts"; import type { TeacherDTO } from "@dwengo-1/common/interfaces/teacher"; import { studentJoinRequestQueryKey, studentJoinRequestsQueryKey } from "@/queries/students.ts"; @@ -33,10 +32,6 @@ function teacherStudentsQueryKey(username: string, full: boolean): [string, stri return ["teacher-students", username, full]; } -function teacherQuestionsQueryKey(username: string, full: boolean): [string, string, boolean] { - return ["teacher-questions", username, full]; -} - export function teacherClassJoinRequests(classId: string): [string, string] { return ["teacher-class-join-requests", classId]; } @@ -80,17 +75,6 @@ export function useTeacherStudentsQuery( }); } -export function useTeacherQuestionsQuery( - username: MaybeRefOrGetter, - full: MaybeRefOrGetter = false, -): UseQueryReturnType { - return useQuery({ - queryKey: computed(() => teacherQuestionsQueryKey(toValue(username)!, toValue(full))), - queryFn: async () => teacherController.getQuestions(toValue(username)!, toValue(full)), - enabled: () => Boolean(toValue(username)), - }); -} - export function useTeacherJoinRequestsQuery( username: MaybeRefOrGetter, classId: MaybeRefOrGetter, diff --git a/frontend/src/views/HomePage.vue b/frontend/src/views/HomePage.vue index 9b2c8acc..c0dcffaf 100644 --- a/frontend/src/views/HomePage.vue +++ b/frontend/src/views/HomePage.vue @@ -28,7 +28,7 @@ alt="Dwengo logo" style="align-self: center" /> -

{{ t("homeTitle") }}

+

{{ t("homeTitle") }}

{{ t("homeIntroduction1") }}

diff --git a/frontend/src/views/assignments/CreateAssignment.vue b/frontend/src/views/assignments/CreateAssignment.vue index 32cda330..50dad4d1 100644 --- a/frontend/src/views/assignments/CreateAssignment.vue +++ b/frontend/src/views/assignments/CreateAssignment.vue @@ -48,7 +48,7 @@ // Disable combobox when learningPath prop is passed const lpIsSelected = route.query.hruid !== undefined; - const deadline = ref(null); + const deadline = ref(new Date()); const description = ref(""); const groups = ref([]); @@ -86,6 +86,7 @@ title: assignmentTitle.value, description: description.value, learningPath: lp || "", + deadline: deadline.value, language: language.value, groups: groups.value, }; @@ -96,7 +97,7 @@ diff --git a/package-lock.json b/package-lock.json index ebf99e7d..43989ba9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2966,21 +2966,6 @@ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", "license": "BSD-3-Clause" }, - "node_modules/@sphinxxxx/color-conversion": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", - "integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==", - "license": "ISC" - }, - "node_modules/@sveltejs/acorn-typescript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", - "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8.9.0" - } - }, "node_modules/@tanstack/match-sorter-utils": { "version": "8.19.4", "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz", @@ -3330,15 +3315,6 @@ "license": "MIT", "optional": true }, - "node_modules/@types/unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/@types/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-D25im2zjyMCcgL9ag6N46+wbtJBnXIr7SI4zHf9eJD2Dw2tEB5e+p5MYkrxKIVRscs5QV0EhtU9rgXSPx90oJg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/web-bluetooth": { "version": "0.0.21", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", @@ -4410,12 +4386,6 @@ "url": "https://github.com/sponsors/antfu" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "license": "MIT" - }, "node_modules/body-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", @@ -4873,32 +4843,12 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/code-block-writer": { "version": "13.0.3", "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", "license": "MIT" }, - "node_modules/codemirror-wrapped-line-indent": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/codemirror-wrapped-line-indent/-/codemirror-wrapped-line-indent-1.0.9.tgz", - "integrity": "sha512-oc976hHLt35u6Ojbhub+IWOxEpapZSqYieLEdGhsgFZ4rtYQtdb5KjxzgjCCyVe3t0yk+a6hmaIOEsjU/tZRxQ==", - "license": "MIT", - "peerDependencies": { - "@codemirror/language": "^6.9.0", - "@codemirror/state": "^6.2.1", - "@codemirror/view": "^6.17.1" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5034,12 +4984,6 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -5364,39 +5308,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", - "license": "BSD", - "dependencies": { - "readable-stream": "~1.1.9" - } - }, - "node_modules/duplexer2/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "license": "MIT" - }, "node_modules/dwengo-1-docs": { "resolved": "docs", "link": true @@ -6005,12 +5916,6 @@ "node": ">=6" } }, - "node_modules/esm-env": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", - "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", - "license": "MIT" - }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", @@ -6312,22 +6217,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -7087,12 +6976,6 @@ "node": ">= 4" } }, - "node_modules/immutable-json-patch": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-6.0.1.tgz", - "integrity": "sha512-BHL/cXMjwFZlTOffiWNdY8ZTvNyYLrutCnWxrcKPHr5FqpAb6vsO6WWSPnVSys3+DruFN6lhHJJPHi8uELQL5g==", - "license": "ISC" - }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -7299,15 +7182,6 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, - "node_modules/is-reference": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.6" - } - }, "node_modules/is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", @@ -8004,12 +7878,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "license": "MIT" - }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -8295,12 +8163,6 @@ "node": ">= 0.8" } }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "license": "MIT" - }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -9908,15 +9770,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -10655,14 +10508,6 @@ "dev": true, "license": "MIT" }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -10831,12 +10676,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", - "license": "MIT" - }, "node_modules/superjson": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", @@ -10875,31 +10714,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svelte": { - "version": "5.28.3", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.28.3.tgz", - "integrity": "sha512-L19exJJQJjwLWgerb9lomqy5BiRGYl+oqshSs7uk3kJ3kCTZokPlJcCe4rSpCzk7f1RFb7bfpvDBe21r1CQ86g==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@jridgewell/sourcemap-codec": "^1.5.0", - "@sveltejs/acorn-typescript": "^1.0.5", - "@types/estree": "^1.0.5", - "acorn": "^8.12.1", - "aria-query": "^5.3.1", - "axobject-query": "^4.1.0", - "clsx": "^2.1.1", - "esm-env": "^1.2.1", - "esrap": "^1.4.6", - "is-reference": "^3.0.3", - "locate-character": "^3.0.0", - "magic-string": "^0.30.11", - "zimmerframe": "^1.1.2" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/swagger-autogen": { "version": "2.23.7", "resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.7.tgz", @@ -11635,71 +11449,6 @@ "dev": true, "license": "MIT" }, - "node_modules/vanilla-jsoneditor": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/vanilla-jsoneditor/-/vanilla-jsoneditor-3.3.1.tgz", - "integrity": "sha512-dnzKiBv7ux7jYAk+FviTQJuL3myEFtvrqnjJfYYmED2ERnirR+CxLinL7pmAER/4UcTMQimnlksTBubf+8eusw==", - "license": "ISC", - "dependencies": { - "@codemirror/autocomplete": "^6.18.1", - "@codemirror/commands": "^6.7.1", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/language": "^6.10.3", - "@codemirror/lint": "^6.8.2", - "@codemirror/search": "^6.5.6", - "@codemirror/state": "^6.4.1", - "@codemirror/view": "^6.34.1", - "@fortawesome/free-regular-svg-icons": "^6.6.0", - "@fortawesome/free-solid-svg-icons": "^6.6.0", - "@jsonquerylang/jsonquery": "^3.1.1 || ^4.0.0", - "@lezer/highlight": "^1.2.1", - "@replit/codemirror-indentation-markers": "^6.5.3", - "ajv": "^8.17.1", - "codemirror-wrapped-line-indent": "^1.0.8", - "diff-sequences": "^29.6.3", - "immutable-json-patch": "^6.0.1", - "jmespath": "^0.16.0", - "json-source-map": "^0.6.1", - "jsonpath-plus": "^10.3.0", - "jsonrepair": "^3.0.0", - "lodash-es": "^4.17.21", - "memoize-one": "^6.0.0", - "natural-compare-lite": "^1.4.0", - "svelte": "^5.0.0", - "vanilla-picker": "^2.12.3" - } - }, - "node_modules/vanilla-jsoneditor/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/vanilla-jsoneditor/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/vanilla-picker": { - "version": "2.12.3", - "resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.12.3.tgz", - "integrity": "sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==", - "license": "ISC", - "dependencies": { - "@sphinxxxx/color-conversion": "^2.2.2" - } - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",