From e6b01fb2e0a7690b81094dc6835773dc78e598b2 Mon Sep 17 00:00:00 2001 From: Matti Lupari Date: Thu, 22 Aug 2024 17:04:49 +0300 Subject: [PATCH] CSCEXAM-000 Reorganize TS models --- .../administrative/administrative.model.ts | 41 ++++ .../categories/enrolments-report.component.ts | 3 +- .../categories/exams-report.component.ts | 3 +- .../categories/records-report.component.ts | 14 -- .../categories/rooms-report.component.ts | 3 +- .../categories/students-report.component.ts | 5 +- .../categories/teachers-report.component.ts | 5 +- .../reports/reports.component.ts | 11 +- .../administrative/reports/reports.service.ts | 13 +- .../settings/settings.component.ts | 3 +- .../settings/settings.service.ts | 25 +-- .../categories/exam-statistics.component.ts | 2 +- .../reservation-statistics.component.ts | 2 +- .../response-statistics.component.ts | 2 +- .../categories/room-statistics.component.ts | 4 +- .../statistics/statistics.component.ts | 3 +- .../statistics/statistics.service.ts | 14 +- .../administrative/users/users.component.ts | 5 +- .../app/administrative/users/users.service.ts | 12 +- ui/src/app/app.component.ts | 2 +- ui/src/app/calendar/calendar.component.ts | 3 +- ui/src/app/calendar/calendar.model.ts | 42 +++++ ui/src/app/calendar/calendar.service.ts | 38 +--- .../helpers/accessibility-picker.component.ts | 2 +- .../calendar/helpers/exam-info.component.ts | 2 +- .../helpers/optional-sections.component.ts | 2 +- .../helpers/organisation-picker.component.ts | 2 +- .../helpers/selected-room.component.ts | 4 +- .../calendar/helpers/slot-picker.component.ts | 5 +- ui/src/app/dashboard/dashboard.model.ts | 40 ++++ .../exam-list-category.component.ts | 11 +- .../teacher/teacher-dashboard.component.ts | 6 +- .../teacher/teacher-dashboard.service.ts | 19 +- .../student/student-dashboard.service.ts | 12 +- ui/src/app/enrolment/enrolment.model.ts | 40 +++- ui/src/app/enrolment/enrolment.service.ts | 23 +-- ...aborative-exam-participations.component.ts | 2 +- .../finished/exam-answers-dialog.component.ts | 6 +- .../finished/exam-participation.component.ts | 4 +- .../finished/exam-participations.component.ts | 2 +- .../collaborative-exam-listing.component.ts | 2 +- .../collaborative-exam.service.ts | 10 +- .../editor/basic/basic-exam-info.component.ts | 2 +- .../basic/exam-inspector-picker.component.ts | 2 +- .../basic/exam-owner-picker.component.ts | 2 +- .../editor/basic/software-picker.component.ts | 3 +- .../examination-type-picker.component.ts | 2 +- .../examination-event-dialog.component.ts | 3 +- ui/src/app/exam/editor/exam-tabs.component.ts | 2 +- ...llaborative-exam-owner-picker.component.ts | 2 +- .../exam-participant-picker.component.ts | 6 +- .../exam-pre-participant-picker.component.ts | 6 +- .../exam-publication.component.html | 54 +----- .../publication/exam-publication.component.ts | 115 +----------- .../examination-events.component.ts | 162 ++++++++++++++++ .../sections/section-question.component.ts | 3 +- .../exam/editor/sections/section.component.ts | 3 +- ui/src/app/exam/exam.model.ts | 176 +----------------- ui/src/app/exam/exam.service.ts | 2 +- .../app/exam/printout/printout.component.ts | 4 +- ui/src/app/examination/examination.model.ts | 3 +- ui/src/app/examination/examination.service.ts | 2 +- .../examination-essay-question.component.ts | 4 +- .../examination-question.component.ts | 2 +- .../app/facility/address/address.component.ts | 2 +- ui/src/app/facility/facility.component.ts | 4 +- ui/src/app/facility/facility.model.ts | 64 +++++++ .../facility/machines/machine.component.ts | 2 +- .../app/facility/machines/machines.service.ts | 2 +- .../facility/rooms/availability.component.ts | 4 +- ui/src/app/facility/rooms/room.service.ts | 30 +-- ui/src/app/facility/rooms/rooms.component.ts | 10 +- .../schedule/exception-dialog.component.ts | 3 +- .../exception-repetition-options.component.ts | 10 +- .../maintenance-period-dialog.component.ts | 2 +- .../schedule/opening-hours.component.ts | 2 +- .../schedule/starting-time.component.ts | 2 +- .../language-inspections.component.ts | 12 +- .../maturity/language-inspections.service.ts | 8 +- .../listing/reviewed-inspections.component.ts | 2 +- .../unfinished-inspections.component.ts | 13 +- ui/src/app/maturity/maturity.model.ts | 20 +- .../reporting/maturity-reporting.component.ts | 5 +- ui/src/app/navigation/navigation.component.ts | 4 +- ui/src/app/navigation/navigation.model.ts | 12 ++ ui/src/app/navigation/navigation.service.ts | 12 +- .../basequestion/claim-choice.component.ts | 4 +- .../question/basequestion/essay.component.ts | 3 +- .../multiple-choice-option.component.ts | 4 +- .../basequestion/multiple-choice.component.ts | 4 +- .../basequestion/question-body.component.ts | 6 +- .../basequestion/question.component.ts | 6 +- ...ighted-multiple-choice-option.component.ts | 3 +- .../base-question-editor.component.ts | 4 +- .../examquestion/claim-choice.component.ts | 2 +- .../exam-question-editor.component.ts | 2 +- .../examquestion/exam-question.component.ts | 8 +- .../examquestion/multichoice.component.ts | 2 +- .../weighted-multichoice.component.ts | 2 +- .../app/question/library/library.component.ts | 4 +- .../app/question/library/library.service.ts | 13 +- .../owners/library-owners-dialog.component.ts | 2 +- .../results/library-results.component.ts | 5 +- .../search/library-search.component.ts | 6 +- .../tags/library-tags-dialog.component.ts | 2 +- .../picker/question-picker.component.ts | 3 +- .../question-preview-dialog.component.ts | 2 +- ui/src/app/question/question.model.ts | 114 ++++++++++++ ui/src/app/question/question.service.ts | 24 +-- .../app/question/tags/tag-picker.component.ts | 6 +- .../admin/change-machine-dialog.component.ts | 3 +- ui/src/app/reservation/reservation.model.ts | 4 +- .../app/reservation/reservations.component.ts | 5 +- .../review/assessment/assessment.component.ts | 7 +- .../review/assessment/assessment.service.ts | 6 +- .../collaborative-assessment.service.ts | 4 +- .../assessment/feedback/feedback.component.ts | 4 +- .../feedback/statement.component.ts | 2 +- .../general/general-info.component.ts | 8 +- .../general/participation.component.ts | 2 +- .../assessment/grading/grading.component.ts | 7 +- .../grading/inspection.component.ts | 2 +- .../assessment/grading/toolbar.component.ts | 2 +- .../assessment/maturity/grading.component.ts | 2 +- .../maturity/inspection-comments.component.ts | 2 +- .../print/printed-assessment.component.ts | 9 +- .../print/printed-cloze-test.component.ts | 2 +- .../print/printed-essay.component.ts | 2 +- .../print/printed-multi-choice.component.ts | 2 +- .../claim-choice-answer.component.ts | 2 +- .../questions/cloze-test.component.ts | 3 +- .../questions/essay-question.component.ts | 9 +- .../multi-choice-answer.component.ts | 2 +- .../multi-choice-question.component.ts | 3 +- .../weighted-multi-choice-answer.component.ts | 3 +- .../assessment/sections/section.component.ts | 4 +- .../listing/categories/archived.component.ts | 3 +- .../categories/graded-logged.component.ts | 3 +- .../listing/categories/graded.component.ts | 3 +- .../in-language-inspection.component.ts | 3 +- .../categories/in-progress.component.ts | 5 +- .../listing/categories/rejected.component.ts | 3 +- .../review/listing/review-list.component.ts | 4 +- .../app/review/listing/review-list.service.ts | 15 +- .../review/listing/speed-review.component.ts | 13 +- .../listing/summary/exam-summary.component.ts | 4 +- .../listing/summary/exam-summary.service.ts | 5 +- .../question-assessment.component.ts | 2 +- .../questions/question-review.service.ts | 2 +- ui/src/app/review/review.model.ts | 30 ++- ui/src/app/session/dev/dev-login.component.ts | 2 +- .../role/role-picker-dialog.component.ts | 2 +- ui/src/app/session/session.model.ts | 40 ++++ ui/src/app/session/session.service.ts | 28 +-- .../app/shared/attachment/attachment.model.ts | 24 +++ .../shared/attachment/attachment.service.ts | 11 +- .../dialogs/attachment-picker.component.ts | 4 - ui/src/app/shared/file/file.service.ts | 3 +- .../app/shared/language/language.service.ts | 4 +- .../select/dropdown-select.component.ts | 8 +- ui/src/app/shared/select/select.model.ts | 10 + .../app/shared/user/teacher-list.component.ts | 2 +- ui/src/app/shared/user/user.service.ts | 2 +- ui/src/app/software/software.component.ts | 2 +- ui/src/styles.scss | 3 + 165 files changed, 928 insertions(+), 878 deletions(-) create mode 100644 ui/src/app/administrative/administrative.model.ts create mode 100644 ui/src/app/calendar/calendar.model.ts create mode 100644 ui/src/app/dashboard/dashboard.model.ts create mode 100644 ui/src/app/exam/editor/publication/examination-events.component.ts create mode 100644 ui/src/app/facility/facility.model.ts create mode 100644 ui/src/app/navigation/navigation.model.ts create mode 100644 ui/src/app/question/question.model.ts create mode 100644 ui/src/app/session/session.model.ts create mode 100644 ui/src/app/shared/attachment/attachment.model.ts create mode 100644 ui/src/app/shared/select/select.model.ts diff --git a/ui/src/app/administrative/administrative.model.ts b/ui/src/app/administrative/administrative.model.ts new file mode 100644 index 000000000..4a8a35835 --- /dev/null +++ b/ui/src/app/administrative/administrative.model.ts @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; + +export type QueryParams = { start?: string; end?: string; dept?: string }; + +export type ExamInfo = { + name: string; + participations: number; + state: string; + rank: number; +}; +export type Participations = { + [room: string]: ExamParticipation[]; +}; + +export interface AppConfig { + eula: string; + examMaxDate: string; + examDurations: number[]; + examMaxDuration: number; + examMinDuration: number; + expirationPeriod: string; + anonymousReviewEnabled: boolean; + hasCourseSearchIntegration: boolean; + hasEnrolmentCheckIntegration: boolean; + isGradeScaleOverridable: boolean; + isInteroperable: boolean; + defaultTimeZone: string; + maxFileSize: number; + reservationWindowSize: number; + reviewDeadline: number; + roles: { ADMIN: string[]; TEACHER: string[]; STUDENT: string[] }; + supportsMaturity: boolean; + supportsPrintouts: boolean; + isExamVisitSupported: boolean; + isExamCollaborationSupported: boolean; + courseSearchIntegrationUrls: { [key: string]: string }; +} diff --git a/ui/src/app/administrative/reports/categories/enrolments-report.component.ts b/ui/src/app/administrative/reports/categories/enrolments-report.component.ts index 1350083a0..347ee0c8e 100644 --- a/ui/src/app/administrative/reports/categories/enrolments-report.component.ts +++ b/ui/src/app/administrative/reports/categories/enrolments-report.component.ts @@ -7,7 +7,8 @@ import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { FileService } from 'src/app/shared/file/file.service'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; @Component({ template: ` diff --git a/ui/src/app/administrative/reports/categories/exams-report.component.ts b/ui/src/app/administrative/reports/categories/exams-report.component.ts index f39b2498c..8efed3ca5 100644 --- a/ui/src/app/administrative/reports/categories/exams-report.component.ts +++ b/ui/src/app/administrative/reports/categories/exams-report.component.ts @@ -7,7 +7,8 @@ import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { FileService } from 'src/app/shared/file/file.service'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; @Component({ template: ` diff --git a/ui/src/app/administrative/reports/categories/records-report.component.ts b/ui/src/app/administrative/reports/categories/records-report.component.ts index 9ea19c306..9724e8315 100644 --- a/ui/src/app/administrative/reports/categories/records-report.component.ts +++ b/ui/src/app/administrative/reports/categories/records-report.component.ts @@ -2,20 +2,6 @@ // // SPDX-License-Identifier: EUPL-1.2 -/* - * Copyright (c) 2018 The members of the EXAM Consortium (https://confluence.csc.fi/display/EXAM/Konsortio-organisaatio) - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European Commission - subsequent - * versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * - * https://joinup.ec.europa.eu/software/page/eupl/licence-eupl - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed - * on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ import { Component } from '@angular/core'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; diff --git a/ui/src/app/administrative/reports/categories/rooms-report.component.ts b/ui/src/app/administrative/reports/categories/rooms-report.component.ts index 665d9639d..0e1c70f02 100644 --- a/ui/src/app/administrative/reports/categories/rooms-report.component.ts +++ b/ui/src/app/administrative/reports/categories/rooms-report.component.ts @@ -10,7 +10,8 @@ import { ToastrService } from 'ngx-toastr'; import type { ExamRoom } from 'src/app/reservation/reservation.model'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; import { FileService } from 'src/app/shared/file/file.service'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; @Component({ template: ` diff --git a/ui/src/app/administrative/reports/categories/students-report.component.ts b/ui/src/app/administrative/reports/categories/students-report.component.ts index 1ec3c385e..80cb61f2a 100644 --- a/ui/src/app/administrative/reports/categories/students-report.component.ts +++ b/ui/src/app/administrative/reports/categories/students-report.component.ts @@ -7,10 +7,11 @@ import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { format } from 'date-fns'; import { ToastrService } from 'ngx-toastr'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; import { FileService } from 'src/app/shared/file/file.service'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; @Component({ template: ` diff --git a/ui/src/app/administrative/reports/categories/teachers-report.component.ts b/ui/src/app/administrative/reports/categories/teachers-report.component.ts index db9068e30..5b400aa98 100644 --- a/ui/src/app/administrative/reports/categories/teachers-report.component.ts +++ b/ui/src/app/administrative/reports/categories/teachers-report.component.ts @@ -7,10 +7,11 @@ import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { format } from 'date-fns'; import { ToastrService } from 'ngx-toastr'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; import { FileService } from 'src/app/shared/file/file.service'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; @Component({ template: ` diff --git a/ui/src/app/administrative/reports/reports.component.ts b/ui/src/app/administrative/reports/reports.component.ts index dec943921..f52d2a2e4 100644 --- a/ui/src/app/administrative/reports/reports.component.ts +++ b/ui/src/app/administrative/reports/reports.component.ts @@ -7,10 +7,10 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { RoomService } from 'src/app/facility/rooms/room.service'; import { ExamRoom } from 'src/app/reservation/reservation.model'; -import { User } from 'src/app/session/session.service'; +import { User } from 'src/app/session/session.model'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; -import { Option } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; import { UserService } from 'src/app/shared/user/user.service'; import { AnswersReportComponent } from './categories/answers-report.component'; import { EnrolmentsReportComponent } from './categories/enrolments-report.component'; @@ -20,8 +20,13 @@ import { ReviewsReportComponent } from './categories/reviews-report.component'; import { RoomsReportComponent } from './categories/rooms-report.component'; import { StudentsReportComponent } from './categories/students-report.component'; import { TeachersReportComponent } from './categories/teachers-report.component'; -import { ReportsService, UserRole } from './reports.service'; +import { ReportsService } from './reports.service'; +enum UserRole { + TEACHER = 'TEACHER', + STUDENT = 'STUDENT', + ADMIN = 'ADMIN', +} @Component({ selector: 'xm-reports', template: ` diff --git a/ui/src/app/administrative/reports/reports.service.ts b/ui/src/app/administrative/reports/reports.service.ts index 448c1060d..82261faba 100644 --- a/ui/src/app/administrative/reports/reports.service.ts +++ b/ui/src/app/administrative/reports/reports.service.ts @@ -5,7 +5,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -export interface ExamName { +interface ExamName { id: number; name: string; course: { @@ -15,17 +15,6 @@ export interface ExamName { }; } -export enum FileType { - JSON = 'json', - XLSX = 'xlsx', -} - -export enum UserRole { - TEACHER = 'TEACHER', - STUDENT = 'STUDENT', - ADMIN = 'ADMIN', -} - @Injectable({ providedIn: 'root' }) export class ReportsService { constructor(private http: HttpClient) {} diff --git a/ui/src/app/administrative/settings/settings.component.ts b/ui/src/app/administrative/settings/settings.component.ts index 63230c0f1..68101a5af 100644 --- a/ui/src/app/administrative/settings/settings.component.ts +++ b/ui/src/app/administrative/settings/settings.component.ts @@ -9,10 +9,11 @@ import { FormsModule } from '@angular/forms'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; +import { AppConfig } from 'src/app/administrative/administrative.model'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; -import { AppConfig, SettingsService } from './settings.service'; +import { SettingsService } from './settings.service'; @Component({ templateUrl: './settings.component.html', diff --git a/ui/src/app/administrative/settings/settings.service.ts b/ui/src/app/administrative/settings/settings.service.ts index b4287ee57..555d944da 100644 --- a/ui/src/app/administrative/settings/settings.service.ts +++ b/ui/src/app/administrative/settings/settings.service.ts @@ -4,30 +4,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; - -export interface AppConfig { - eula: string; - examMaxDate: string; - examDurations: number[]; - examMaxDuration: number; - examMinDuration: number; - expirationPeriod: string; - anonymousReviewEnabled: boolean; - hasCourseSearchIntegration: boolean; - hasEnrolmentCheckIntegration: boolean; - isGradeScaleOverridable: boolean; - isInteroperable: boolean; - defaultTimeZone: string; - maxFileSize: number; - reservationWindowSize: number; - reviewDeadline: number; - roles: { ADMIN: string[]; TEACHER: string[]; STUDENT: string[] }; - supportsMaturity: boolean; - supportsPrintouts: boolean; - isExamVisitSupported: boolean; - isExamCollaborationSupported: boolean; - courseSearchIntegrationUrls: { [key: string]: string }; -} +import { AppConfig } from 'src/app/administrative/administrative.model'; @Injectable({ providedIn: 'root' }) export class SettingsService { diff --git a/ui/src/app/administrative/statistics/categories/exam-statistics.component.ts b/ui/src/app/administrative/statistics/categories/exam-statistics.component.ts index 7560cc18b..1f5b01608 100644 --- a/ui/src/app/administrative/statistics/categories/exam-statistics.component.ts +++ b/ui/src/app/administrative/statistics/categories/exam-statistics.component.ts @@ -5,7 +5,7 @@ import type { OnInit } from '@angular/core'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamInfo, QueryParams } from 'src/app/administrative/statistics/statistics.service'; +import { ExamInfo, QueryParams } from 'src/app/administrative/administrative.model'; import { StatisticsService } from 'src/app/administrative/statistics/statistics.service'; @Component({ diff --git a/ui/src/app/administrative/statistics/categories/reservation-statistics.component.ts b/ui/src/app/administrative/statistics/categories/reservation-statistics.component.ts index 620f423f6..943645668 100644 --- a/ui/src/app/administrative/statistics/categories/reservation-statistics.component.ts +++ b/ui/src/app/administrative/statistics/categories/reservation-statistics.component.ts @@ -5,7 +5,7 @@ import type { OnInit } from '@angular/core'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { QueryParams } from 'src/app/administrative/statistics/statistics.service'; +import { QueryParams } from 'src/app/administrative/administrative.model'; import { StatisticsService } from 'src/app/administrative/statistics/statistics.service'; @Component({ diff --git a/ui/src/app/administrative/statistics/categories/response-statistics.component.ts b/ui/src/app/administrative/statistics/categories/response-statistics.component.ts index dd80c7cde..f87ba1463 100644 --- a/ui/src/app/administrative/statistics/categories/response-statistics.component.ts +++ b/ui/src/app/administrative/statistics/categories/response-statistics.component.ts @@ -5,7 +5,7 @@ import type { OnInit } from '@angular/core'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { QueryParams } from 'src/app/administrative/statistics/statistics.service'; +import { QueryParams } from 'src/app/administrative/administrative.model'; import { StatisticsService } from 'src/app/administrative/statistics/statistics.service'; import type { Exam } from 'src/app/exam/exam.model'; diff --git a/ui/src/app/administrative/statistics/categories/room-statistics.component.ts b/ui/src/app/administrative/statistics/categories/room-statistics.component.ts index 0b4fa5535..c4f3a1352 100644 --- a/ui/src/app/administrative/statistics/categories/room-statistics.component.ts +++ b/ui/src/app/administrative/statistics/categories/room-statistics.component.ts @@ -5,9 +5,9 @@ import { DatePipe } from '@angular/common'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { Participations, QueryParams } from 'src/app/administrative/statistics/statistics.service'; +import { Participations, QueryParams } from 'src/app/administrative/administrative.model'; import { StatisticsService } from 'src/app/administrative/statistics/statistics.service'; -import type { ExamParticipation } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; @Component({ template: ` diff --git a/ui/src/app/administrative/statistics/statistics.component.ts b/ui/src/app/administrative/statistics/statistics.component.ts index c5a7777ac..a2226e520 100644 --- a/ui/src/app/administrative/statistics/statistics.component.ts +++ b/ui/src/app/administrative/statistics/statistics.component.ts @@ -17,6 +17,7 @@ import { NgbNavLink, } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; +import { QueryParams } from 'src/app/administrative/administrative.model'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; @@ -24,7 +25,7 @@ import { ExamStatisticsComponent } from './categories/exam-statistics.component' import { ReservationStatisticsComponent } from './categories/reservation-statistics.component'; import { ResponseStatisticsComponent } from './categories/response-statistics.component'; import { RoomStatisticsComponent } from './categories/room-statistics.component'; -import { QueryParams, StatisticsService } from './statistics.service'; +import { StatisticsService } from './statistics.service'; interface Departments { name: string; diff --git a/ui/src/app/administrative/statistics/statistics.service.ts b/ui/src/app/administrative/statistics/statistics.service.ts index edf035dc7..f16f77e24 100644 --- a/ui/src/app/administrative/statistics/statistics.service.ts +++ b/ui/src/app/administrative/statistics/statistics.service.ts @@ -4,18 +4,8 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Exam, ExamParticipation } from 'src/app/exam/exam.model'; - -export type QueryParams = { start?: string; end?: string; dept?: string }; -export type ExamInfo = { - name: string; - participations: number; - state: string; - rank: number; -}; -export type Participations = { - [room: string]: ExamParticipation[]; -}; +import { ExamInfo, Participations, QueryParams } from 'src/app/administrative/administrative.model'; +import { Exam } from 'src/app/exam/exam.model'; @Injectable({ providedIn: 'root' }) export class StatisticsService { diff --git a/ui/src/app/administrative/users/users.component.ts b/ui/src/app/administrative/users/users.component.ts index 9a9080f8b..fd144db29 100644 --- a/ui/src/app/administrative/users/users.component.ts +++ b/ui/src/app/administrative/users/users.component.ts @@ -17,13 +17,12 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; -import type { User } from 'src/app/session/session.service'; +import { PermissionType, type Permission, type User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { PaginatorComponent } from 'src/app/shared/paginator/paginator.component'; -import type { Permission } from './users.service'; -import { PermissionType, UserManagementService } from './users.service'; +import { UserManagementService } from './users.service'; interface PermissionOption extends Permission { name?: string; diff --git a/ui/src/app/administrative/users/users.service.ts b/ui/src/app/administrative/users/users.service.ts index 9a208e396..2a482a8ac 100644 --- a/ui/src/app/administrative/users/users.service.ts +++ b/ui/src/app/administrative/users/users.service.ts @@ -4,17 +4,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import type { Role, User } from 'src/app/session/session.service'; - -export enum PermissionType { - CAN_INSPECT_LANGUAGE = 'CAN_INSPECT_LANGUAGE', - CAN_CREATE_BYOD_EXAM = 'CAN_CREATE_BYOD_EXAM', -} - -export interface Permission { - id: number; - type: PermissionType; -} +import type { Permission, PermissionType, Role, User } from 'src/app/session/session.model'; @Injectable({ providedIn: 'root' }) export class UserManagementService { diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index cd1256312..e3f89cba8 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -13,7 +13,7 @@ import { takeUntil } from 'rxjs/operators'; import { ExaminationStatusService } from './examination/examination-status.service'; import { NavigationComponent } from './navigation/navigation.component'; import { DevLoginComponent } from './session/dev/dev-login.component'; -import type { User } from './session/session.service'; +import type { User } from './session/session.model'; import { SessionService } from './session/session.service'; @Component({ diff --git a/ui/src/app/calendar/calendar.component.ts b/ui/src/app/calendar/calendar.component.ts index 3e5503139..3ffe23dfa 100644 --- a/ui/src/app/calendar/calendar.component.ts +++ b/ui/src/app/calendar/calendar.component.ts @@ -19,7 +19,8 @@ import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-d import { HistoryBackComponent } from 'src/app/shared/history/history-back.component'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; import { AutoFocusDirective } from 'src/app/shared/select/auto-focus.directive'; -import { CalendarService, ExamInfo, Organisation } from './calendar.service'; +import { ExamInfo, Organisation } from './calendar.model'; +import { CalendarService } from './calendar.service'; import { CalendarExamInfoComponent } from './helpers/exam-info.component'; import { OptionalSectionsComponent } from './helpers/optional-sections.component'; import { OrganisationPickerComponent } from './helpers/organisation-picker.component'; diff --git a/ui/src/app/calendar/calendar.model.ts b/ui/src/app/calendar/calendar.model.ts new file mode 100644 index 000000000..be57f9afd --- /dev/null +++ b/ui/src/app/calendar/calendar.model.ts @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +import { Course, Exam, ExamSection } from 'src/app/exam/exam.model'; +import { Accessibility, ExamRoom } from 'src/app/reservation/reservation.model'; + +export interface Slot { + start: string; + end: string; + conflictingExam?: boolean; + roomId: number | string; + examId: number; + orgId: string | null; + aids?: number[]; + sectionIds: number[]; +} + +export interface OpeningHours { + name: string; + ref: string; + ord: number; + periods: string[]; + periodText?: string; +} + +export type SelectableSection = ExamSection & { selected: boolean }; +export type ExamInfo = Omit, 'course' | 'examSections'> & { course: Course } & { + duration: number; + examSections: (ExamSection & { selected: boolean })[]; +}; +export type Organisation = { + _id: string; + name: string; + code: string; + filtered: boolean; + homeOrg: string; + facilities: ExamRoom[]; +}; +export type AvailableSlot = Slot & { availableMachines: number }; + +export type FilterableAccessibility = Accessibility & { filtered: boolean }; diff --git a/ui/src/app/calendar/calendar.service.ts b/ui/src/app/calendar/calendar.service.ts index 0dfd484a2..f1a6dca62 100644 --- a/ui/src/app/calendar/calendar.service.ts +++ b/ui/src/app/calendar/calendar.service.ts @@ -7,7 +7,7 @@ import { Injectable } from '@angular/core'; import { DateTime, Interval } from 'luxon'; import type { Observable } from 'rxjs'; import { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; -import { Course, Exam, ExamSection, MaintenancePeriod } from 'src/app/exam/exam.model'; +import { MaintenancePeriod } from 'src/app/facility/facility.model'; import type { Accessibility, DefaultWorkingHours, @@ -16,48 +16,14 @@ import type { } from 'src/app/reservation/reservation.model'; import { SessionService } from 'src/app/session/session.service'; import { DateTimeService } from 'src/app/shared/date/date.service'; +import { AvailableSlot, ExamInfo, OpeningHours, Organisation, Slot } from './calendar.model'; type WeekdayNames = Record; -export interface Slot { - start: string; - end: string; - conflictingExam?: boolean; - roomId: number | string; - examId: number; - orgId: string | null; - aids?: number[]; - sectionIds: number[]; -} - -export interface OpeningHours { - name: string; - ref: string; - ord: number; - periods: string[]; - periodText?: string; -} - -export type SelectableSection = ExamSection & { selected: boolean }; -export type ExamInfo = Omit, 'course' | 'examSections'> & { course: Course } & { - duration: number; - examSections: (ExamSection & { selected: boolean })[]; -}; -export type Organisation = { - _id: string; - name: string; - code: string; - filtered: boolean; - homeOrg: string; - facilities: ExamRoom[]; -}; -export type AvailableSlot = Slot & { availableMachines: number }; - @Injectable({ providedIn: 'root' }) export class CalendarService { constructor( private http: HttpClient, - private DateTimeService: DateTimeService, private Session: SessionService, ) {} diff --git a/ui/src/app/calendar/helpers/accessibility-picker.component.ts b/ui/src/app/calendar/helpers/accessibility-picker.component.ts index 0207b79a8..1c7bac9db 100644 --- a/ui/src/app/calendar/helpers/accessibility-picker.component.ts +++ b/ui/src/app/calendar/helpers/accessibility-picker.component.ts @@ -5,7 +5,7 @@ import { Component, EventEmitter, Input, Output, signal } from '@angular/core'; import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import { FilterableAccessibility } from './slot-picker.component'; +import { FilterableAccessibility } from 'src/app/calendar/calendar.model'; @Component({ selector: 'xm-calendar-accessibility-picker', diff --git a/ui/src/app/calendar/helpers/exam-info.component.ts b/ui/src/app/calendar/helpers/exam-info.component.ts index 68fe52a75..0a0967bcb 100644 --- a/ui/src/app/calendar/helpers/exam-info.component.ts +++ b/ui/src/app/calendar/helpers/exam-info.component.ts @@ -6,7 +6,7 @@ import { DatePipe } from '@angular/common'; import { Component, Input, OnInit, computed, signal } from '@angular/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { DateTime } from 'luxon'; -import type { ExamInfo } from 'src/app/calendar/calendar.service'; +import type { ExamInfo } from 'src/app/calendar/calendar.model'; import { DateTimeService } from 'src/app/shared/date/date.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; diff --git a/ui/src/app/calendar/helpers/optional-sections.component.ts b/ui/src/app/calendar/helpers/optional-sections.component.ts index fac743255..10f9c1f31 100644 --- a/ui/src/app/calendar/helpers/optional-sections.component.ts +++ b/ui/src/app/calendar/helpers/optional-sections.component.ts @@ -6,7 +6,7 @@ import { NgClass, UpperCasePipe } from '@angular/common'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamInfo } from 'src/app/calendar/calendar.service'; +import type { ExamInfo } from 'src/app/calendar/calendar.model'; @Component({ selector: 'xm-calendar-optional-sections', diff --git a/ui/src/app/calendar/helpers/organisation-picker.component.ts b/ui/src/app/calendar/helpers/organisation-picker.component.ts index de00cf8d6..483130a1c 100644 --- a/ui/src/app/calendar/helpers/organisation-picker.component.ts +++ b/ui/src/app/calendar/helpers/organisation-picker.component.ts @@ -6,7 +6,7 @@ import { NgClass } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output, signal } from '@angular/core'; import { NgbDropdown, NgbDropdownItem, NgbDropdownMenu, NgbDropdownToggle } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import type { Organisation } from 'src/app/calendar/calendar.service'; +import type { Organisation } from 'src/app/calendar/calendar.model'; import { CalendarService } from 'src/app/calendar/calendar.service'; @Component({ diff --git a/ui/src/app/calendar/helpers/selected-room.component.ts b/ui/src/app/calendar/helpers/selected-room.component.ts index 643540ade..c5200a94c 100644 --- a/ui/src/app/calendar/helpers/selected-room.component.ts +++ b/ui/src/app/calendar/helpers/selected-room.component.ts @@ -7,9 +7,9 @@ import { Component, Input, OnChanges, OnInit, signal } from '@angular/core'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { DateTime } from 'luxon'; -import type { OpeningHours } from 'src/app/calendar/calendar.service'; +import type { OpeningHours } from 'src/app/calendar/calendar.model'; import { CalendarService } from 'src/app/calendar/calendar.service'; -import { MaintenancePeriod } from 'src/app/exam/exam.model'; +import { MaintenancePeriod } from 'src/app/facility/facility.model'; import type { ExamRoom, ExceptionWorkingHours } from 'src/app/reservation/reservation.model'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; diff --git a/ui/src/app/calendar/helpers/slot-picker.component.ts b/ui/src/app/calendar/helpers/slot-picker.component.ts index 144d5ea7d..050f533fb 100644 --- a/ui/src/app/calendar/helpers/slot-picker.component.ts +++ b/ui/src/app/calendar/helpers/slot-picker.component.ts @@ -20,15 +20,14 @@ import { DateTime } from 'luxon'; import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { BookingCalendarComponent } from 'src/app/calendar/booking-calendar.component'; -import type { Organisation, Slot } from 'src/app/calendar/calendar.service'; +import type { FilterableAccessibility, Organisation, Slot } from 'src/app/calendar/calendar.model'; import { CalendarService } from 'src/app/calendar/calendar.service'; -import { MaintenancePeriod } from 'src/app/exam/exam.model'; +import { MaintenancePeriod } from 'src/app/facility/facility.model'; import type { Accessibility, ExamRoom } from 'src/app/reservation/reservation.model'; import { updateList } from 'src/app/shared/miscellaneous/helpers'; import { AccessibilityPickerComponent } from './accessibility-picker.component'; import { SelectedRoomComponent } from './selected-room.component'; -export type FilterableAccessibility = Accessibility & { filtered: boolean }; type FilterableRoom = ExamRoom & { filtered: boolean }; type AvailableSlot = Slot & { availableMachines: number }; diff --git a/ui/src/app/dashboard/dashboard.model.ts b/ui/src/app/dashboard/dashboard.model.ts new file mode 100644 index 000000000..7f9612f50 --- /dev/null +++ b/ui/src/app/dashboard/dashboard.model.ts @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +import { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; +import { Exam, ExamExecutionType } from 'src/app/exam/exam.model'; + +export interface Occasion { + startAt: string; + endAt: string; + tz: string; +} + +export interface DashboardExam extends Exam { + ownerAggregate: string; + unassessedCount: number; + unfinishedCount: number; + reservationCount: number; + assessedCount: number; +} + +export interface DashboardEnrolment extends ExamEnrolment { + occasion?: Occasion; + startAtAggregate: string; +} + +export class Dashboard { + executionTypes: ExamExecutionType[] = []; + draftExams: DashboardExam[] = []; + activeExams: DashboardExam[] = []; + finishedExams: DashboardExam[] = []; + archivedExams: DashboardExam[] = []; +} + +export interface ExtraData { + text: string; + property: keyof DashboardExam; + link: string[]; + checkOwnership: boolean; +} diff --git a/ui/src/app/dashboard/staff/teacher/categories/exam-list-category.component.ts b/ui/src/app/dashboard/staff/teacher/categories/exam-list-category.component.ts index ceeb453b0..86bb13a1a 100644 --- a/ui/src/app/dashboard/staff/teacher/categories/exam-list-category.component.ts +++ b/ui/src/app/dashboard/staff/teacher/categories/exam-list-category.component.ts @@ -12,7 +12,8 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { Subject, from } from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators'; -import { DashboardExam, TeacherDashboardService } from 'src/app/dashboard/staff/teacher/teacher-dashboard.service'; +import { DashboardExam, ExtraData } from 'src/app/dashboard/dashboard.model'; +import { TeacherDashboardService } from 'src/app/dashboard/staff/teacher/teacher-dashboard.service'; import { ExaminationTypeSelectorComponent } from 'src/app/exam/editor/common/examination-type-picker.component'; import type { Exam } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; @@ -24,12 +25,7 @@ import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.co import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; import { TableSortComponent } from 'src/app/shared/sorting/table-sort.component'; import { TeacherListComponent } from 'src/app/shared/user/teacher-list.component'; -export interface ExtraData { - text: string; - property: keyof DashboardExam; - link: string[]; - checkOwnership: boolean; -} + @Component({ selector: 'xm-exam-list-category', templateUrl: './exam-list-category.component.html', @@ -49,7 +45,6 @@ export interface ExtraData { }) export class ExamListCategoryComponent implements OnInit, OnDestroy { @Input() items: DashboardExam[] = []; - @Input() extraData: ExtraData[] = []; @Input() defaultPredicate = ''; @Input() defaultReverse = false; diff --git a/ui/src/app/dashboard/staff/teacher/teacher-dashboard.component.ts b/ui/src/app/dashboard/staff/teacher/teacher-dashboard.component.ts index 5d3f012a0..7f77b9794 100644 --- a/ui/src/app/dashboard/staff/teacher/teacher-dashboard.component.ts +++ b/ui/src/app/dashboard/staff/teacher/teacher-dashboard.component.ts @@ -15,13 +15,13 @@ import { NgbNavOutlet, } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; +import { DashboardExam, ExtraData } from 'src/app/dashboard/dashboard.model'; import { Exam } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; -import { ExamListCategoryComponent, ExtraData } from './categories/exam-list-category.component'; -import type { DashboardExam } from './teacher-dashboard.service'; +import { ExamListCategoryComponent } from './categories/exam-list-category.component'; import { TeacherDashboardService } from './teacher-dashboard.service'; @Component({ diff --git a/ui/src/app/dashboard/staff/teacher/teacher-dashboard.service.ts b/ui/src/app/dashboard/staff/teacher/teacher-dashboard.service.ts index 2d2c6e588..9ededb696 100644 --- a/ui/src/app/dashboard/staff/teacher/teacher-dashboard.service.ts +++ b/ui/src/app/dashboard/staff/teacher/teacher-dashboard.service.ts @@ -7,26 +7,11 @@ import { Injectable } from '@angular/core'; import type { Observable } from 'rxjs'; import { forkJoin } from 'rxjs'; import { map } from 'rxjs/operators'; -import type { Exam, ExamExecutionType } from 'src/app/exam/exam.model'; +import { Dashboard } from 'src/app/dashboard/dashboard.model'; +import type { Exam } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; import { ReservationService } from 'src/app/reservation/reservation.service'; -export interface DashboardExam extends Exam { - ownerAggregate: string; - unassessedCount: number; - unfinishedCount: number; - reservationCount: number; - assessedCount: number; -} - -export class Dashboard { - executionTypes: ExamExecutionType[] = []; - draftExams: DashboardExam[] = []; - activeExams: DashboardExam[] = []; - finishedExams: DashboardExam[] = []; - archivedExams: DashboardExam[] = []; -} - @Injectable({ providedIn: 'root' }) export class TeacherDashboardService { constructor( diff --git a/ui/src/app/dashboard/student/student-dashboard.service.ts b/ui/src/app/dashboard/student/student-dashboard.service.ts index 7db8fbce7..eca76b2ab 100644 --- a/ui/src/app/dashboard/student/student-dashboard.service.ts +++ b/ui/src/app/dashboard/student/student-dashboard.service.ts @@ -7,21 +7,11 @@ import { Injectable } from '@angular/core'; import { DateTime } from 'luxon'; import type { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { DashboardEnrolment, Occasion } from 'src/app/dashboard/dashboard.model'; import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; import type { Reservation } from 'src/app/reservation/reservation.model'; import { DateTimeService } from 'src/app/shared/date/date.service'; -interface Occasion { - startAt: string; - endAt: string; - tz: string; -} - -export interface DashboardEnrolment extends ExamEnrolment { - occasion?: Occasion; - startAtAggregate: string; -} - @Injectable({ providedIn: 'root' }) export class StudentDashboardService { constructor( diff --git a/ui/src/app/enrolment/enrolment.model.ts b/ui/src/app/enrolment/enrolment.model.ts index 78ce78c1f..a831c3189 100644 --- a/ui/src/app/enrolment/enrolment.model.ts +++ b/ui/src/app/enrolment/enrolment.model.ts @@ -6,12 +6,13 @@ import type { CollaborativeExam, Course, Exam, + ExaminationEvent, ExaminationEventConfiguration, ExamInspection, ExamSection, } from 'src/app/exam/exam.model'; import type { Reservation } from 'src/app/reservation/reservation.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; export interface Scores { maxScore: number; @@ -37,6 +38,43 @@ export interface ExternalExam { creator: User; } +export interface ExamParticipation { + id: number; + exam: Exam; + ended: string; + started: string; + reservation?: Reservation; + examinationEvent?: ExaminationEvent; + collaborativeExam?: CollaborativeExam; + externalExam?: { started: Date }; + user: User; + duration: string; + deadline: string; + displayName?: string; + _id?: string; + _rev?: string; +} + +export function isParticipation(event: ExamParticipation | ExamEnrolment): event is ExamParticipation { + return ( + event.reservation !== null && + event.reservation !== undefined && + event.reservation.enrolment.noShow === undefined // FIXME: check this + ); +} + +export type CollaborativeParticipation = Omit & { exam: ReviewedExam } & { + examId: string; + noShow: false; + _id: string; + _rev: string; +}; + +export type ParticipationLike = + | (ExamParticipation & { noShow: boolean }) + | (CollaborativeParticipation & { noShow: boolean }) + | (ExamEnrolment & { started?: string; ended?: string; duration?: number }); + export interface ExamEnrolment { id: number; information: string; diff --git a/ui/src/app/enrolment/enrolment.service.ts b/ui/src/app/enrolment/enrolment.service.ts index 48cb97a67..959e26a9d 100644 --- a/ui/src/app/enrolment/enrolment.service.ts +++ b/ui/src/app/enrolment/enrolment.service.ts @@ -10,26 +10,21 @@ import { TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { forkJoin, from, Observable, of, throwError } from 'rxjs'; import { catchError, map, switchMap, tap } from 'rxjs/operators'; -import { CollaborativeParticipation } from 'src/app/exam/collaborative/collaborative-exam.service'; -import type { - CollaborativeExam, - Exam, - ExaminationEventConfiguration, - ExamParticipation, -} from 'src/app/exam/exam.model'; +import type { CollaborativeExam, Exam, ExaminationEventConfiguration } from 'src/app/exam/exam.model'; import type { ExamRoom } from 'src/app/reservation/reservation.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { isObject } from 'src/app/shared/miscellaneous/helpers'; import { AddEnrolmentInformationDialogComponent } from './active/dialogs/add-enrolment-information-dialog.component'; import { SelectExaminationEventDialogComponent } from './active/dialogs/select-examination-event-dialog.component'; import { ShowInstructionsDialogComponent } from './active/dialogs/show-instructions-dialog.component'; -import type { EnrolmentInfo, ExamEnrolment, ReviewedExam } from './enrolment.model'; - -export type ParticipationLike = - | (ExamParticipation & { noShow: boolean }) - | (CollaborativeParticipation & { noShow: boolean }) - | (ExamEnrolment & { started?: string; ended?: string; duration?: number }); +import type { + CollaborativeParticipation, + EnrolmentInfo, + ExamEnrolment, + ParticipationLike, + ReviewedExam, +} from './enrolment.model'; @Injectable({ providedIn: 'root' }) export class EnrolmentService { diff --git a/ui/src/app/enrolment/finished/collaborative-exam-participations.component.ts b/ui/src/app/enrolment/finished/collaborative-exam-participations.component.ts index 47929abcc..a3548a92f 100644 --- a/ui/src/app/enrolment/finished/collaborative-exam-participations.component.ts +++ b/ui/src/app/enrolment/finished/collaborative-exam-participations.component.ts @@ -9,8 +9,8 @@ import { FormsModule } from '@angular/forms'; import { NgbDropdown, NgbDropdownItem, NgbDropdownMenu, NgbDropdownToggle } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; +import { CollaborativeParticipation } from 'src/app/enrolment/enrolment.model'; import { EnrolmentService } from 'src/app/enrolment/enrolment.service'; -import type { CollaborativeParticipation } from 'src/app/exam/collaborative/collaborative-exam.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { PaginatorComponent } from 'src/app/shared/paginator/paginator.component'; diff --git a/ui/src/app/enrolment/finished/exam-answers-dialog.component.ts b/ui/src/app/enrolment/finished/exam-answers-dialog.component.ts index 5992a829d..ffc808333 100644 --- a/ui/src/app/enrolment/finished/exam-answers-dialog.component.ts +++ b/ui/src/app/enrolment/finished/exam-answers-dialog.component.ts @@ -6,8 +6,10 @@ import { DatePipe, UpperCasePipe } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import { Exam, ExamSectionQuestion } from 'src/app/exam/exam.model'; -import { AnsweredQuestion, AttachmentService } from 'src/app/shared/attachment/attachment.service'; +import { Exam } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; +import { AnsweredQuestion } from 'src/app/shared/attachment/attachment.model'; +import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; diff --git a/ui/src/app/enrolment/finished/exam-participation.component.ts b/ui/src/app/enrolment/finished/exam-participation.component.ts index 85cbffce9..c33d6e1f6 100644 --- a/ui/src/app/enrolment/finished/exam-participation.component.ts +++ b/ui/src/app/enrolment/finished/exam-participation.component.ts @@ -9,10 +9,8 @@ import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import type { ReviewedExam } from 'src/app/enrolment/enrolment.model'; -import type { ParticipationLike } from 'src/app/enrolment/enrolment.service'; +import type { CollaborativeParticipation, ParticipationLike, ReviewedExam } from 'src/app/enrolment/enrolment.model'; import { EnrolmentService } from 'src/app/enrolment/enrolment.service'; -import type { CollaborativeParticipation } from 'src/app/exam/collaborative/collaborative-exam.service'; import type { Exam } from 'src/app/exam/exam.model'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; diff --git a/ui/src/app/enrolment/finished/exam-participations.component.ts b/ui/src/app/enrolment/finished/exam-participations.component.ts index c78b5296a..dd53c83f4 100644 --- a/ui/src/app/enrolment/finished/exam-participations.component.ts +++ b/ui/src/app/enrolment/finished/exam-participations.component.ts @@ -11,7 +11,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; -import type { ParticipationLike } from 'src/app/enrolment/enrolment.service'; +import { ParticipationLike } from 'src/app/enrolment/enrolment.model'; import { EnrolmentService } from 'src/app/enrolment/enrolment.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/exam/collaborative/collaborative-exam-listing.component.ts b/ui/src/app/exam/collaborative/collaborative-exam-listing.component.ts index d0b87933d..d37cf0fa1 100644 --- a/ui/src/app/exam/collaborative/collaborative-exam-listing.component.ts +++ b/ui/src/app/exam/collaborative/collaborative-exam-listing.component.ts @@ -13,7 +13,7 @@ import { Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, exhaustMap, map, switchMap, takeUntil, tap } from 'rxjs/operators'; import type { CollaborativeExam } from 'src/app/exam/exam.model'; import { CollaborativeExamState } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/exam/collaborative/collaborative-exam.service.ts b/ui/src/app/exam/collaborative/collaborative-exam.service.ts index d580ec2f9..f5bad8e2e 100644 --- a/ui/src/app/exam/collaborative/collaborative-exam.service.ts +++ b/ui/src/app/exam/collaborative/collaborative-exam.service.ts @@ -5,18 +5,10 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import type { Observable } from 'rxjs'; -import type { ReviewedExam } from 'src/app/enrolment/enrolment.model'; -import type { CollaborativeExam, Exam, ExamParticipation } from 'src/app/exam/exam.model'; +import type { CollaborativeExam, Exam } from 'src/app/exam/exam.model'; import { CollaborativeExamState } from 'src/app/exam/exam.model'; import { SessionService } from 'src/app/session/session.service'; -export type CollaborativeParticipation = Omit & { exam: ReviewedExam } & { - examId: string; - noShow: false; - _id: string; - _rev: string; -}; - @Injectable({ providedIn: 'root' }) export class CollaborativeExamService { exams: CollaborativeExam[] = []; diff --git a/ui/src/app/exam/editor/basic/basic-exam-info.component.ts b/ui/src/app/exam/editor/basic/basic-exam-info.component.ts index ab19c56ed..eada7d644 100644 --- a/ui/src/app/exam/editor/basic/basic-exam-info.component.ts +++ b/ui/src/app/exam/editor/basic/basic-exam-info.component.ts @@ -16,7 +16,7 @@ import { LanguageSelectorComponent } from 'src/app/exam/editor/common/language-p import { ExamTabService } from 'src/app/exam/editor/exam-tabs.service'; import type { Exam, ExamType, GradeScale } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; diff --git a/ui/src/app/exam/editor/basic/exam-inspector-picker.component.ts b/ui/src/app/exam/editor/basic/exam-inspector-picker.component.ts index c5482b5c5..dd07ef678 100644 --- a/ui/src/app/exam/editor/basic/exam-inspector-picker.component.ts +++ b/ui/src/app/exam/editor/basic/exam-inspector-picker.component.ts @@ -13,7 +13,7 @@ import type { Observable } from 'rxjs'; import { of, throwError } from 'rxjs'; import { catchError, debounceTime, distinctUntilChanged, exhaustMap, take, tap } from 'rxjs/operators'; import type { Exam, ExamInspection } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; @Component({ selector: 'xm-exam-inspector-picker', diff --git a/ui/src/app/exam/editor/basic/exam-owner-picker.component.ts b/ui/src/app/exam/editor/basic/exam-owner-picker.component.ts index 6bfc7e4a5..a2dc17355 100644 --- a/ui/src/app/exam/editor/basic/exam-owner-picker.component.ts +++ b/ui/src/app/exam/editor/basic/exam-owner-picker.component.ts @@ -14,7 +14,7 @@ import type { Observable } from 'rxjs'; import { of, throwError } from 'rxjs'; import { catchError, debounceTime, distinctUntilChanged, exhaustMap, take, tap } from 'rxjs/operators'; import type { Exam } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; @Component({ selector: 'xm-exam-owner-picker', diff --git a/ui/src/app/exam/editor/basic/software-picker.component.ts b/ui/src/app/exam/editor/basic/software-picker.component.ts index 3dbe1e58b..cf4f04e36 100644 --- a/ui/src/app/exam/editor/basic/software-picker.component.ts +++ b/ui/src/app/exam/editor/basic/software-picker.component.ts @@ -15,7 +15,8 @@ import { } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { Exam, Software } from 'src/app/exam/exam.model'; +import type { Exam } from 'src/app/exam/exam.model'; +import { Software } from 'src/app/facility/facility.model'; @Component({ selector: 'xm-software-picker', diff --git a/ui/src/app/exam/editor/common/examination-type-picker.component.ts b/ui/src/app/exam/editor/common/examination-type-picker.component.ts index 696cc75b1..8cbbc25b5 100644 --- a/ui/src/app/exam/editor/common/examination-type-picker.component.ts +++ b/ui/src/app/exam/editor/common/examination-type-picker.component.ts @@ -9,7 +9,7 @@ import { NgbAccordionDirective, NgbAccordionModule, NgbActiveModal } from '@ng-b import { TranslateModule } from '@ngx-translate/core'; import { ExamService } from 'src/app/exam/exam.service'; -export type ExamConfig = { type: string; name: string; examinationTypes: { type: string; name: string }[] }; +type ExamConfig = { type: string; name: string; examinationTypes: { type: string; name: string }[] }; @Component({ selector: 'xm-examination-type-selector', diff --git a/ui/src/app/exam/editor/events/examination-event-dialog.component.ts b/ui/src/app/exam/editor/events/examination-event-dialog.component.ts index 44f4df950..506db83e2 100644 --- a/ui/src/app/exam/editor/events/examination-event-dialog.component.ts +++ b/ui/src/app/exam/editor/events/examination-event-dialog.component.ts @@ -10,8 +10,9 @@ import { FormsModule } from '@angular/forms'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExaminationEvent, ExaminationEventConfiguration, MaintenancePeriod } from 'src/app/exam/exam.model'; +import type { ExaminationEvent, ExaminationEventConfiguration } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; +import { MaintenancePeriod } from 'src/app/facility/facility.model'; import { DateTimePickerComponent } from 'src/app/shared/date/date-time-picker.component'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; diff --git a/ui/src/app/exam/editor/exam-tabs.component.ts b/ui/src/app/exam/editor/exam-tabs.component.ts index 0c9d29b0c..7bfc1e1c6 100644 --- a/ui/src/app/exam/editor/exam-tabs.component.ts +++ b/ui/src/app/exam/editor/exam-tabs.component.ts @@ -11,7 +11,7 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import type { Exam } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/exam/editor/publication/collaborative-exam-owner-picker.component.ts b/ui/src/app/exam/editor/publication/collaborative-exam-owner-picker.component.ts index 1f53ac353..4005820ac 100644 --- a/ui/src/app/exam/editor/publication/collaborative-exam-owner-picker.component.ts +++ b/ui/src/app/exam/editor/publication/collaborative-exam-owner-picker.component.ts @@ -10,7 +10,7 @@ import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import type { Exam } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; @Component({ diff --git a/ui/src/app/exam/editor/publication/exam-participant-picker.component.ts b/ui/src/app/exam/editor/publication/exam-participant-picker.component.ts index 4eed61a83..e98983125 100644 --- a/ui/src/app/exam/editor/publication/exam-participant-picker.component.ts +++ b/ui/src/app/exam/editor/publication/exam-participant-picker.component.ts @@ -13,10 +13,10 @@ import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { from } from 'rxjs'; import { debounceTime, distinctUntilChanged, exhaustMap, take, tap } from 'rxjs/operators'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { EnrolmentService } from 'src/app/enrolment/enrolment.service'; -import type { Exam, ExamParticipation } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { Exam } from 'src/app/exam/exam.model'; +import type { User } from 'src/app/session/session.model'; @Component({ selector: 'xm-exam-participant-selector', diff --git a/ui/src/app/exam/editor/publication/exam-pre-participant-picker.component.ts b/ui/src/app/exam/editor/publication/exam-pre-participant-picker.component.ts index e8ec3be59..978e00f2b 100644 --- a/ui/src/app/exam/editor/publication/exam-pre-participant-picker.component.ts +++ b/ui/src/app/exam/editor/publication/exam-pre-participant-picker.component.ts @@ -8,10 +8,10 @@ import { Component, Input, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { EnrolmentService } from 'src/app/enrolment/enrolment.service'; -import type { Exam, ExamParticipation } from 'src/app/exam/exam.model'; -import { User } from 'src/app/session/session.service'; +import type { Exam } from 'src/app/exam/exam.model'; +import { User } from 'src/app/session/session.model'; @Component({ selector: 'xm-exam-pre-participant-selector', diff --git a/ui/src/app/exam/editor/publication/exam-publication.component.html b/ui/src/app/exam/editor/publication/exam-publication.component.html index 057429926..67e83e430 100644 --- a/ui/src/app/exam/editor/publication/exam-publication.component.html +++ b/ui/src/app/exam/editor/publication/exam-publication.component.html @@ -89,59 +89,7 @@ - - @if (exam.implementation !== 'AQUARIUM') { -
-
- {{ 'i18n_examination_events' | translate }} - - - -
-
- -
-
-
    - @for (config of sortByString(exam.examinationEventConfigurations); track config) { -
  • - - {{ config.examinationEvent.start | date: 'dd.MM.yyyy HH:mm' - }} - - @if (config.examEnrolments.length === 0) { - - - } @else { - - - - } -
  • - } -
-
-
- } +
diff --git a/ui/src/app/exam/editor/publication/exam-publication.component.ts b/ui/src/app/exam/editor/publication/exam-publication.component.ts index 379949682..41b27e0b3 100644 --- a/ui/src/app/exam/editor/publication/exam-publication.component.ts +++ b/ui/src/app/exam/editor/publication/exam-publication.component.ts @@ -15,26 +15,17 @@ import { Duration } from 'luxon'; import { ToastrService } from 'ngx-toastr'; import { Observable, from, throwError } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; -import { ExaminationEventDialogComponent } from 'src/app/exam/editor/events/examination-event-dialog.component'; import { ExamTabService } from 'src/app/exam/editor/exam-tabs.service'; -import type { - AutoEvaluationConfig, - Exam, - ExaminationDate, - ExaminationEventConfiguration, - MaintenancePeriod, -} from 'src/app/exam/exam.model'; +import type { AutoEvaluationConfig, Exam, ExaminationDate } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; import { SessionService } from 'src/app/session/session.service'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; -import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { isBoolean } from 'src/app/shared/miscellaneous/helpers'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; import { CollaborativeExamOwnerSelectorComponent } from './collaborative-exam-owner-picker.component'; import { CustomDurationPickerDialogComponent } from './custom-duration-picker-dialog.component'; -import { ExamParticipantSelectorComponent } from './exam-participant-picker.component'; -import { ExamPreParticipantSelectorComponent } from './exam-pre-participant-picker.component'; import { ExamPublicationParticipantsComponent } from './exam-publication-participants.component'; +import { ExaminationEventsComponent } from './examination-events.component'; import { OrganisationSelectorComponent } from './organisation-picker.component'; import { PublicationDialogComponent } from './publication-dialog.component'; import { PublicationErrorDialogComponent } from './publication-error-dialog.component'; @@ -50,10 +41,9 @@ import { PublicationRevocationDialogComponent } from './publication-revocation-d NgbPopover, NgClass, ExamPublicationParticipantsComponent, - ExamParticipantSelectorComponent, - ExamPreParticipantSelectorComponent, CollaborativeExamOwnerSelectorComponent, OrganisationSelectorComponent, + ExaminationEventsComponent, UpperCasePipe, DatePipe, TranslateModule, @@ -63,13 +53,11 @@ import { PublicationRevocationDialogComponent } from './publication-revocation-d }) export class ExamPublicationComponent implements OnInit { exam!: Exam; - maintenancePeriods: MaintenancePeriod[] = []; collaborative = signal(false); isAdmin = signal(false); hostName = signal(''); examDurations = signal([]); - visibleParticipantSelector = signal('participant'); constructor( private http: HttpClient, @@ -80,7 +68,6 @@ export class ExamPublicationComponent implements OnInit { private toast: ToastrService, private Session: SessionService, private Exam: ExamService, - private Confirmation: ConfirmationDialogService, private Tabs: ExamTabService, ) { this.hostName.set(window.location.origin); @@ -94,11 +81,6 @@ export class ExamPublicationComponent implements OnInit { next: (data) => this.examDurations.set(data.examDurations), error: (err) => this.toast.error(err), }); - if (this.exam.implementation !== 'AQUARIUM') { - this.http - .get('/app/maintenance') - .subscribe((periods) => (this.maintenancePeriods = periods)); - } this.Tabs.notifyTabChange(4); } @@ -244,73 +226,6 @@ export class ExamPublicationComponent implements OnInit { } }; - isPeriodOver = () => new Date(this.exam.periodEnd as string) < new Date(); - - addExaminationEvent = () => { - const modalRef = this.modal.open(ExaminationEventDialogComponent, { - backdrop: 'static', - keyboard: true, - size: 'lg', - }); - modalRef.componentInstance.requiresPassword = this.exam.implementation === 'CLIENT_AUTH'; - modalRef.componentInstance.examMinDate = this.exam.periodStart; - modalRef.componentInstance.examMaxDate = this.exam.periodEnd; - modalRef.componentInstance.maintenancePeriods = this.maintenancePeriods; - modalRef.componentInstance.examId = this.exam.id; - modalRef.componentInstance.duration = this.exam.duration; - modalRef.result - .then((data: ExaminationEventConfiguration) => this.exam.examinationEventConfigurations.push(data)) - .catch((err) => { - if (err) this.toast.error(err); - }); - }; - - modifyExaminationEvent = (configuration: ExaminationEventConfiguration) => { - const modalRef = this.modal.open(ExaminationEventDialogComponent, { - backdrop: 'static', - keyboard: true, - size: 'lg', - }); - modalRef.componentInstance.config = configuration; - modalRef.componentInstance.requiresPassword = this.exam.implementation === 'CLIENT_AUTH'; - modalRef.componentInstance.examMaxDate = this.exam.periodEnd; - modalRef.componentInstance.maintenancePeriods = this.maintenancePeriods; - modalRef.componentInstance.examId = this.exam.id; - modalRef.componentInstance.duration = this.exam.duration; - modalRef.result - .then((config: ExaminationEventConfiguration) => { - const index = this.exam.examinationEventConfigurations.indexOf(configuration); - this.exam.examinationEventConfigurations.splice(index, 1, config); - }) - .catch((err) => { - if (err) this.toast.error(err); - }); - }; - - removeExaminationEvent = (configuration: ExaminationEventConfiguration) => { - if (configuration.examEnrolments.length > 0) { - return; - } - this.Confirmation.open$( - this.translate.instant('i18n_remove_examination_event'), - this.translate.instant('i18n_are_you_sure'), - ).subscribe({ - next: () => - this.Exam.removeExaminationEvent$(this.exam.id, configuration).subscribe({ - next: () => { - this.exam.examinationEventConfigurations.splice( - this.exam.examinationEventConfigurations.indexOf(configuration), - 1, - ); - }, - error: (err) => this.toast.error(err), - }), - }); - }; - - sortByString = (prop: ExaminationEventConfiguration[]): Array => - prop.sort((a, b) => Date.parse(a.examinationEvent.start) - Date.parse(b.examinationEvent.start)); - private updateExam$ = (silent?: boolean, overrides?: Record): Observable => { return this.Exam.updateExam$(this.exam, overrides, this.collaborative()).pipe( tap(() => { @@ -333,31 +248,22 @@ export class ExamPublicationComponent implements OnInit { private hasDuplicatePercentages = () => { if (!this.exam.autoEvaluationConfig) return false; - const percentages = this.exam.autoEvaluationConfig.gradeEvaluations.map((e) => e.percentage).sort(); - for (let i = 0; i < percentages.length - 1; ++i) { - if (percentages[i + 1] === percentages[i]) { - return true; - } - } - return false; + const percentages = this.exam.autoEvaluationConfig.gradeEvaluations.map((e) => e.percentage); + return new Set(percentages).size !== percentages.length; }; private errorsPreventingPrePublication(): string[] { - const errors: string[] = []; - + const errors = []; if (!this.exam.name || this.exam.name.length < 2) { errors.push('i18n_exam_name_missing_or_too_short'); } - if (this.exam.examLanguages.length === 0) { errors.push('i18n_error_exam_empty_exam_language'); } - const isPrintout = this.exam.executionType.type === 'PRINTOUT'; if (!isPrintout && !this.exam.periodStart) { errors.push('i18n_exam_start_date_missing'); } - if (!isPrintout && !this.exam.periodEnd) { errors.push('i18n_exam_end_date_missing'); } @@ -367,45 +273,36 @@ export class ExamPublicationComponent implements OnInit { if (!this.exam.duration) { errors.push('i18n_exam_duration_missing'); } - if (!this.exam.gradeScale) { errors.push('i18n_exam_grade_scale_missing'); } - if (!this.exam.examType) { errors.push('i18n_exam_credit_type_missing'); } if (this.exam.examOwners.length == 0) { errors.push('i18n_exam_owner_missing'); } - return errors; } private errorsPreventingPublication(): string[] { const errors: string[] = this.errorsPreventingPrePublication(); - if (!this.exam.course && !this.collaborative) { errors.push('i18n_course_missing'); } - if (this.countQuestions() === 0) { errors.push('i18n_exam_has_no_questions'); } - const allSectionsNamed = this.exam.examSections.every((section) => section.name?.length > 0); if (!allSectionsNamed) { errors.push('i18n_exam_contains_unnamed_sections'); } - if (['PRIVATE', 'MATURITY'].indexOf(this.exam.executionType.type) > -1 && this.exam.examEnrolments.length < 1) { errors.push('i18n_no_participants'); } - if (this.exam.executionType.type === 'MATURITY' && !isBoolean(this.exam.subjectToLanguageInspection)) { errors.push('i18n_language_inspection_setting_not_chosen'); } - if (this.hasDuplicatePercentages()) { errors.push('i18n_autoevaluation_percentages_not_unique'); } diff --git a/ui/src/app/exam/editor/publication/examination-events.component.ts b/ui/src/app/exam/editor/publication/examination-events.component.ts new file mode 100644 index 000000000..466c619c5 --- /dev/null +++ b/ui/src/app/exam/editor/publication/examination-events.component.ts @@ -0,0 +1,162 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +import { DatePipe } from '@angular/common'; +import { HttpClient } from '@angular/common/http'; +import { Component, input, OnInit, signal } from '@angular/core'; +import { NgbModal, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { ToastrService } from 'ngx-toastr'; +import { ExaminationEventDialogComponent } from 'src/app/exam/editor/events/examination-event-dialog.component'; +import { Exam, ExaminationEventConfiguration } from 'src/app/exam/exam.model'; +import { ExamService } from 'src/app/exam/exam.service'; +import { MaintenancePeriod } from 'src/app/facility/facility.model'; +import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; + +@Component({ + standalone: true, + imports: [NgbPopoverModule, TranslateModule, DatePipe], + selector: 'xm-examination-events', + template: ` + + @if (exam().implementation !== 'AQUARIUM') { +
+
+ {{ 'i18n_examination_events' | translate }} + + + +
+
+ +
+
+
    + @for (config of sortByString(exam().examinationEventConfigurations); track config) { +
  • + + {{ config.examinationEvent.start | date: 'dd.MM.yyyy HH:mm' + }} + + @if (config.examEnrolments.length === 0) { + + + } @else { + + + + } +
  • + } +
+
+
+ } + `, +}) +export class ExaminationEventsComponent implements OnInit { + exam = input.required(); + maintenancePeriods = signal([]); + + constructor( + private HttpClient: HttpClient, + private ModalService: NgbModal, + private ToastrService: ToastrService, + private TranslateService: TranslateService, + private ConfirmationDialogService: ConfirmationDialogService, + private ExamService: ExamService, + ) {} + + ngOnInit() { + this.HttpClient.get('/app/maintenance').subscribe((periods) => + this.maintenancePeriods.set(periods), + ); + } + + isPeriodOver = () => new Date(this.exam().periodEnd as string) < new Date(); + + addExaminationEvent = () => { + const modalRef = this.ModalService.open(ExaminationEventDialogComponent, { + backdrop: 'static', + keyboard: true, + size: 'lg', + }); + modalRef.componentInstance.requiresPassword = this.exam().implementation === 'CLIENT_AUTH'; + modalRef.componentInstance.examMinDate = this.exam().periodStart; + modalRef.componentInstance.examMaxDate = this.exam().periodEnd; + modalRef.componentInstance.maintenancePeriods = this.maintenancePeriods(); + modalRef.componentInstance.examId = this.exam().id; + modalRef.componentInstance.duration = this.exam().duration; + modalRef.result + .then((data: ExaminationEventConfiguration) => this.exam().examinationEventConfigurations.push(data)) + .catch((err) => { + if (err) this.ToastrService.error(err); + }); + }; + + modifyExaminationEvent = (configuration: ExaminationEventConfiguration) => { + const modalRef = this.ModalService.open(ExaminationEventDialogComponent, { + backdrop: 'static', + keyboard: true, + size: 'lg', + }); + modalRef.componentInstance.config = configuration; + modalRef.componentInstance.requiresPassword = this.exam().implementation === 'CLIENT_AUTH'; + modalRef.componentInstance.examMaxDate = this.exam().periodEnd; + modalRef.componentInstance.maintenancePeriods = this.maintenancePeriods(); + modalRef.componentInstance.examId = this.exam().id; + modalRef.componentInstance.duration = this.exam().duration; + modalRef.result + .then((config: ExaminationEventConfiguration) => { + const index = this.exam().examinationEventConfigurations.indexOf(configuration); + this.exam().examinationEventConfigurations.splice(index, 1, config); // CHECK + }) + .catch((err) => { + if (err) this.ToastrService.error(err); + }); + }; + + removeExaminationEvent = (configuration: ExaminationEventConfiguration) => { + if (configuration.examEnrolments.length > 0) { + return; + } + this.ConfirmationDialogService.open$( + this.TranslateService.instant('i18n_remove_examination_event'), + this.TranslateService.instant('i18n_are_you_sure'), + ).subscribe({ + next: () => + this.ExamService.removeExaminationEvent$(this.exam().id, configuration).subscribe({ + next: () => { + this.exam().examinationEventConfigurations.splice( + this.exam().examinationEventConfigurations.indexOf(configuration), + 1, + ); + }, + error: (err) => this.ToastrService.error(err), + }), + }); + }; + + sortByString = (prop: ExaminationEventConfiguration[]): ExaminationEventConfiguration[] => + prop.sort((a, b) => Date.parse(a.examinationEvent.start) - Date.parse(b.examinationEvent.start)); +} diff --git a/ui/src/app/exam/editor/sections/section-question.component.ts b/ui/src/app/exam/editor/sections/section-question.component.ts index dcc489067..a098447fa 100644 --- a/ui/src/app/exam/editor/sections/section-question.component.ts +++ b/ui/src/app/exam/editor/sections/section-question.component.ts @@ -19,9 +19,10 @@ import { ToastrService } from 'ngx-toastr'; import { mergeDeepRight } from 'ramda'; import { Observable, from, noop, of } from 'rxjs'; import { map } from 'rxjs/operators'; -import type { ExamSection, ExamSectionQuestion, ExamSectionQuestionOption, Question } from 'src/app/exam/exam.model'; +import type { ExamSection } from 'src/app/exam/exam.model'; import { BaseQuestionEditorComponent } from 'src/app/question/examquestion/base-question-editor.component'; import { ExamQuestionEditorComponent } from 'src/app/question/examquestion/exam-question-editor.component'; +import { ExamSectionQuestion, ExamSectionQuestionOption, Question } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; diff --git a/ui/src/app/exam/editor/sections/section.component.ts b/ui/src/app/exam/editor/sections/section.component.ts index 926074205..03377bea3 100644 --- a/ui/src/app/exam/editor/sections/section.component.ts +++ b/ui/src/app/exam/editor/sections/section.component.ts @@ -26,10 +26,11 @@ import { import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { from, noop } from 'rxjs'; -import type { ExamMaterial, ExamSection, ExamSectionQuestion, Question } from 'src/app/exam/exam.model'; +import type { ExamMaterial, ExamSection } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; import { BaseQuestionEditorComponent } from 'src/app/question/examquestion/base-question-editor.component'; import { QuestionSelectorComponent } from 'src/app/question/picker/question-picker.component'; +import { ExamSectionQuestion, Question } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { FileService } from 'src/app/shared/file/file.service'; diff --git a/ui/src/app/exam/exam.model.ts b/ui/src/app/exam/exam.model.ts index 30521c46d..66e9631b0 100644 --- a/ui/src/app/exam/exam.model.ts +++ b/ui/src/app/exam/exam.model.ts @@ -2,11 +2,14 @@ // // SPDX-License-Identifier: EUPL-1.2 -import { Organisation } from 'src/app/calendar/calendar.service'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; +import { Organisation } from 'src/app/calendar/calendar.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import { Software } from 'src/app/facility/facility.model'; import type { LanguageInspection } from 'src/app/maturity/maturity.model'; -import type { Reservation } from 'src/app/reservation/reservation.model'; -import type { User } from 'src/app/session/session.service'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; +import { Feedback } from 'src/app/review/review.model'; +import type { User } from 'src/app/session/session.model'; +import { Attachment } from 'src/app/shared/attachment/attachment.model'; export interface Grade { id: number; @@ -74,124 +77,10 @@ export interface ExamLanguage { name: string; } -export interface Attachment { - id?: number; - externalId?: string; - fileName: string; - removed: boolean; - modified: boolean; - size: number; - file?: File; - rev?: string; - objectVersion?: number; -} export interface ReverseExamSection extends ExamSection { exam: Exam; } -export interface ReverseExamSectionQuestion extends ExamSectionQuestion { - examSection: ReverseExamSection; -} - -export interface ReverseQuestion extends Question { - examSectionQuestions: ReverseExamSectionQuestion[]; -} - -export interface Tag { - id?: number; - name: string; - creator?: User; - questions: Question[]; -} - -export interface Question { - id: number; - question: string; - creator?: User; - type: string; - attachment?: Attachment; - options: MultipleChoiceOption[]; - tags: Tag[]; - questionOwners: User[]; - parent?: Question; - state: string; - defaultMaxScore?: number; - modifier?: User; - modified?: Date; - shared?: boolean; - defaultAnswerInstructions?: string; - defaultEvaluationCriteria?: string; - defaultExpectedWordCount?: number; - defaultEvaluationType?: string; -} - -export interface EssayAnswer { - id?: number; - evaluatedScore?: number; - answer?: string; - objectVersion?: number; - attachment?: Attachment; -} - -export interface MultipleChoiceOption { - id?: number; - option: string; - correctOption: boolean; - defaultScore: number; - claimChoiceType?: string; -} - -export interface ExamSectionQuestionOption { - id?: number; - score: number; - answered: boolean; - option: MultipleChoiceOption; -} - -export interface ContentElement { - order: number; - type: string; -} -export interface TextElement extends ContentElement { - text: string; -} -export function isTextElement(element: ContentElement): element is TextElement { - return element.type === 'Text'; -} -export function isBlankElement(element: ContentElement): element is BlankElement { - return element.type === 'Blank'; -} -interface BlankElement extends ContentElement { - id: string; - numeric: boolean; -} -export interface ClozeTestAnswer { - id: number; - score?: { correctAnswers: number; incorrectAnswers: number }; - maxScore: number; - answer: string; - objectVersion: number; - question: string; -} - -export interface ExamSectionQuestion { - id: number; - question: Question; - evaluationType?: string; - forcedScore: number | null; - maxScore: number; - essayAnswer?: EssayAnswer; - clozeTestAnswer?: ClozeTestAnswer; - options: ExamSectionQuestionOption[]; - answerInstructions: string; - evaluationCriteria: string; - expectedWordCount?: number; - sequenceNumber: number; - expanded: boolean; - derivedMaxScore?: number; - derivedAssessedScore?: number; -} - export interface ExamMaterial { id: number; name: string; @@ -232,13 +121,6 @@ export interface CollaborativeExam { externalRef?: string; } -export interface Feedback { - comment: string; - id?: number; - attachment?: Attachment; - feedbackStatus?: boolean; -} - export interface ExaminationEvent { id?: number; start: string; @@ -264,12 +146,6 @@ export interface ExamInspection { ready: boolean; } -export interface Software { - id: number; - name: string; - turnedOn: boolean; -} - export interface ExamType { id: number; type: string; @@ -341,41 +217,3 @@ export interface ExamImpl { export interface Exam extends ExamImpl { answerLanguage?: string; } - -export interface ExamParticipation { - id: number; - exam: Exam; - ended: string; - started: string; - reservation?: Reservation; - examinationEvent?: ExaminationEvent; - collaborativeExam?: CollaborativeExam; - externalExam?: { started: Date }; - user: User; - duration: string; - deadline: string; - displayName?: string; - _id?: string; - _rev?: string; -} - -export function isParticipation(event: ExamParticipation | ExamEnrolment): event is ExamParticipation { - return ( - event.reservation !== null && - event.reservation !== undefined && - event.reservation.enrolment.noShow === undefined // FIXME: check this - ); -} - -export enum ClaimChoiceOptionType { - CorrectOption = 'CorrectOption', - IncorrectOption = 'IncorrectOption', - SkipOption = 'SkipOption', -} - -export type MaintenancePeriod = { - id?: number; - startsAt: string; - endsAt: string; - description: string; -}; diff --git a/ui/src/app/exam/exam.service.ts b/ui/src/app/exam/exam.service.ts index 44fbdb53d..60c727cde 100644 --- a/ui/src/app/exam/exam.service.ts +++ b/ui/src/app/exam/exam.service.ts @@ -24,7 +24,7 @@ import type { Implementation, } from './exam.model'; -export type ExaminationEventConfigurationInput = { +type ExaminationEventConfigurationInput = { id?: number; config: { examinationEvent: { diff --git a/ui/src/app/exam/printout/printout.component.ts b/ui/src/app/exam/printout/printout.component.ts index 80e79ad67..544d7e33b 100644 --- a/ui/src/app/exam/printout/printout.component.ts +++ b/ui/src/app/exam/printout/printout.component.ts @@ -8,7 +8,9 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { map } from 'rxjs/operators'; -import type { Attachment, ClozeTestAnswer, Exam, ExamLanguage, ExamSectionQuestion } from 'src/app/exam/exam.model'; +import type { Exam, ExamLanguage } from 'src/app/exam/exam.model'; +import { ClozeTestAnswer, ExamSectionQuestion } from 'src/app/question/question.model'; +import { Attachment } from 'src/app/shared/attachment/attachment.model'; import { FileService } from 'src/app/shared/file/file.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; diff --git a/ui/src/app/examination/examination.model.ts b/ui/src/app/examination/examination.model.ts index 014951c6b..93ebf2b92 100644 --- a/ui/src/app/examination/examination.model.ts +++ b/ui/src/app/examination/examination.model.ts @@ -1,7 +1,8 @@ // SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium // // SPDX-License-Identifier: EUPL-1.2 -import type { Exam, ExamSection, ExamSectionQuestion, ExamSectionQuestionOption } from 'src/app/exam/exam.model'; +import type { Exam, ExamSection } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion, ExamSectionQuestionOption } from 'src/app/question/question.model'; export interface Examination extends Exam { cloned: boolean; external: boolean; diff --git a/ui/src/app/examination/examination.service.ts b/ui/src/app/examination/examination.service.ts index d4992928c..0234920b9 100644 --- a/ui/src/app/examination/examination.service.ts +++ b/ui/src/app/examination/examination.service.ts @@ -9,7 +9,7 @@ import { TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { concat, Observable, of, throwError } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; -import type { ClozeTestAnswer, EssayAnswer } from 'src/app/exam/exam.model'; +import { ClozeTestAnswer, EssayAnswer } from 'src/app/question/question.model'; import type { Examination, ExaminationQuestion, ExaminationSection } from './examination.model'; @Injectable({ providedIn: 'root' }) diff --git a/ui/src/app/examination/question/examination-essay-question.component.ts b/ui/src/app/examination/question/examination-essay-question.component.ts index ae49eaddd..b0150cb17 100644 --- a/ui/src/app/examination/question/examination-essay-question.component.ts +++ b/ui/src/app/examination/question/examination-essay-question.component.ts @@ -6,10 +6,10 @@ import { DatePipe, UpperCasePipe } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; -import type { EssayAnswer } from 'src/app/exam/exam.model'; import type { Examination, ExaminationQuestion } from 'src/app/examination/examination.model'; import { ExaminationService } from 'src/app/examination/examination.service'; -import type { AnsweredQuestion } from 'src/app/shared/attachment/attachment.service'; +import { EssayAnswer } from 'src/app/question/question.model'; +import type { AnsweredQuestion } from 'src/app/shared/attachment/attachment.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; import { FileService } from 'src/app/shared/file/file.service'; diff --git a/ui/src/app/examination/question/examination-question.component.ts b/ui/src/app/examination/question/examination-question.component.ts index 4f1b984ed..779df643f 100644 --- a/ui/src/app/examination/question/examination-question.component.ts +++ b/ui/src/app/examination/question/examination-question.component.ts @@ -6,9 +6,9 @@ import { NgClass, SlicePipe, UpperCasePipe } from '@angular/common'; import type { AfterViewInit } from '@angular/core'; import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { EssayAnswer } from 'src/app/exam/exam.model'; import type { Examination, ExaminationQuestion } from 'src/app/examination/examination.model'; import { ExaminationService } from 'src/app/examination/examination.service'; +import { EssayAnswer } from 'src/app/question/question.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { DynamicClozeTestComponent } from './dynamic-cloze-test.component'; diff --git a/ui/src/app/facility/address/address.component.ts b/ui/src/app/facility/address/address.component.ts index 0da6f1f1e..abc414310 100644 --- a/ui/src/app/facility/address/address.component.ts +++ b/ui/src/app/facility/address/address.component.ts @@ -7,7 +7,7 @@ import { FormsModule, NgForm } from '@angular/forms'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { Address } from 'src/app/facility/rooms/room.service'; +import { Address } from 'src/app/facility/facility.model'; import { RoomService } from 'src/app/facility/rooms/room.service'; @Component({ diff --git a/ui/src/app/facility/facility.component.ts b/ui/src/app/facility/facility.component.ts index c9a5498e3..2dc23dfc5 100644 --- a/ui/src/app/facility/facility.component.ts +++ b/ui/src/app/facility/facility.component.ts @@ -17,14 +17,14 @@ import { import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { from } from 'rxjs'; -import type { MaintenancePeriod } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; import { SoftwareComponent } from 'src/app/software/software.component'; import { AccessibilityComponent } from './accessibility/accessibility.component'; +import { MaintenancePeriod } from './facility.model'; import { RoomService } from './rooms/room.service'; import { RoomListComponent } from './rooms/rooms.component'; import { MaintenancePeriodDialogComponent } from './schedule/maintenance-period-dialog.component'; diff --git a/ui/src/app/facility/facility.model.ts b/ui/src/app/facility/facility.model.ts new file mode 100644 index 000000000..53855d125 --- /dev/null +++ b/ui/src/app/facility/facility.model.ts @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +import { DefaultWorkingHours } from 'src/app/reservation/reservation.model'; + +export interface Software { + id: number; + name: string; + turnedOn: boolean; +} + +export type MaintenancePeriod = { + id?: number; + startsAt: string; + endsAt: string; + description: string; +}; + +export type Weekday = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY'; + +export interface Day { + index: number; + type: string; +} + +export type Week = { [day: string]: Day[] }; + +export interface WorkingHour { + startingHour: string; + selected: boolean; +} + +export interface DefaultWorkingHoursWithEditing extends DefaultWorkingHours { + editing: boolean; + pickStartingTime: { hour: number; minute: number; second: number; millisecond?: number }; + pickEndingTime: { hour: number; minute: number; second: number; millisecond?: number }; + displayStartingTime: { hour: number; minute: number; second: number; millisecond?: number }; + displayEndingTime: { hour: number; minute: number; second: number; millisecond?: number }; +} + +export interface Availability { + start: string; + end: string; + total: number; + reserved: number; +} + +export interface Address { + id: number; + city: string; + zip: string; + street: string; +} + +export type RepetitionConfig = { + start: Date; + end: Date; + weekdays: { ord: number; name: string }[]; + dayOfMonth?: number; + monthlyOrdinal?: { name: string; ord: number }; + monthlyWeekday?: { name: string; ord: number }; + yearlyMonth?: { name: string; ord: number }; +}; diff --git a/ui/src/app/facility/machines/machine.component.ts b/ui/src/app/facility/machines/machine.component.ts index 0196731f6..3dffb5075 100644 --- a/ui/src/app/facility/machines/machine.component.ts +++ b/ui/src/app/facility/machines/machine.component.ts @@ -9,7 +9,7 @@ import { FormsModule } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { Software } from 'src/app/exam/exam.model'; +import { Software } from 'src/app/facility/facility.model'; import type { ExamMachine } from 'src/app/reservation/reservation.model'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/facility/machines/machines.service.ts b/ui/src/app/facility/machines/machines.service.ts index a29184af7..c6f6d1698 100644 --- a/ui/src/app/facility/machines/machines.service.ts +++ b/ui/src/app/facility/machines/machines.service.ts @@ -4,7 +4,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import type { Software } from 'src/app/exam/exam.model'; +import { Software } from 'src/app/facility/facility.model'; import type { ExamMachine } from 'src/app/reservation/reservation.model'; @Injectable({ providedIn: 'root' }) diff --git a/ui/src/app/facility/rooms/availability.component.ts b/ui/src/app/facility/rooms/availability.component.ts index 8238865e5..b32642910 100644 --- a/ui/src/app/facility/rooms/availability.component.ts +++ b/ui/src/app/facility/rooms/availability.component.ts @@ -11,10 +11,10 @@ import { TranslateModule } from '@ngx-translate/core'; import { DateTime } from 'luxon'; import { ToastrService } from 'ngx-toastr'; import { BookingCalendarComponent } from 'src/app/calendar/booking-calendar.component'; -import type { OpeningHours } from 'src/app/calendar/calendar.service'; +import type { OpeningHours } from 'src/app/calendar/calendar.model'; import { CalendarService } from 'src/app/calendar/calendar.service'; +import { Availability } from 'src/app/facility/facility.model'; import type { ExamRoom, ExceptionWorkingHours } from 'src/app/reservation/reservation.model'; -import type { Availability } from './room.service'; import { RoomService } from './room.service'; @Component({ diff --git a/ui/src/app/facility/rooms/room.service.ts b/ui/src/app/facility/rooms/room.service.ts index eef98644a..470ae6f89 100644 --- a/ui/src/app/facility/rooms/room.service.ts +++ b/ui/src/app/facility/rooms/room.service.ts @@ -9,40 +9,12 @@ import { TranslateService } from '@ngx-translate/core'; import { format, formatISO, parseISO, setHours, setMinutes } from 'date-fns'; import { ToastrService } from 'ngx-toastr'; import { noop } from 'rxjs'; -import { MaintenancePeriod } from 'src/app/exam/exam.model'; +import { Address, Availability, MaintenancePeriod, WorkingHour } from 'src/app/facility/facility.model'; import { ExceptionDialogComponent } from 'src/app/facility/schedule/exception-dialog.component'; import type { DefaultWorkingHours, ExamRoom, ExceptionWorkingHours } from 'src/app/reservation/reservation.model'; import { DateTimeService } from 'src/app/shared/date/date.service'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; -export type Weekday = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY'; - -export interface Day { - index: number; - type: string; -} - -export type Week = { [day: string]: Day[] }; - -export interface WorkingHour { - startingHour: string; - selected: boolean; -} - -export interface Availability { - start: string; - end: string; - total: number; - reserved: number; -} - -export interface Address { - id: number; - city: string; - zip: string; - street: string; -} - @Injectable({ providedIn: 'root' }) export class RoomService { constructor( diff --git a/ui/src/app/facility/rooms/rooms.component.ts b/ui/src/app/facility/rooms/rooms.component.ts index a198a2708..1206531e9 100644 --- a/ui/src/app/facility/rooms/rooms.component.ts +++ b/ui/src/app/facility/rooms/rooms.component.ts @@ -10,13 +10,14 @@ import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { format, parseISO } from 'date-fns'; import { ToastrService } from 'ngx-toastr'; +import { DefaultWorkingHoursWithEditing } from 'src/app/facility/facility.model'; import { MachineListComponent } from 'src/app/facility/machines/machines.component'; import { ExceptionListComponent } from 'src/app/facility/schedule/exceptions.component'; import { OpenHoursComponent } from 'src/app/facility/schedule/opening-hours.component'; import { StartingTimeComponent } from 'src/app/facility/schedule/starting-time.component'; import type { DefaultWorkingHours, ExamRoom } from 'src/app/reservation/reservation.model'; import { ExceptionWorkingHours } from 'src/app/reservation/reservation.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { DateTimeService } from 'src/app/shared/date/date.service'; import { groupBy } from 'src/app/shared/miscellaneous/helpers'; @@ -28,13 +29,6 @@ interface ExtendedRoom extends ExamRoom { extendedDwh: DefaultWorkingHoursWithEditing[]; activate: boolean; } -export interface DefaultWorkingHoursWithEditing extends DefaultWorkingHours { - editing: boolean; - pickStartingTime: { hour: number; minute: number; second: number; millisecond?: number }; - pickEndingTime: { hour: number; minute: number; second: number; millisecond?: number }; - displayStartingTime: { hour: number; minute: number; second: number; millisecond?: number }; - displayEndingTime: { hour: number; minute: number; second: number; millisecond?: number }; -} @Component({ templateUrl: './rooms.component.html', diff --git a/ui/src/app/facility/schedule/exception-dialog.component.ts b/ui/src/app/facility/schedule/exception-dialog.component.ts index e6b09126a..c275cea2f 100644 --- a/ui/src/app/facility/schedule/exception-dialog.component.ts +++ b/ui/src/app/facility/schedule/exception-dialog.component.ts @@ -9,10 +9,11 @@ import { addDays, areIntervalsOverlapping, eachDayOfInterval, getDate, getDay, g import { DateTime } from 'luxon'; import { ToastrService } from 'ngx-toastr'; import { groupBy } from 'ramda'; +import { RepetitionConfig } from 'src/app/facility/facility.model'; import { ExceptionWorkingHours } from 'src/app/reservation/reservation.model'; import { DateTimeService, REPEAT_OPTION } from 'src/app/shared/date/date.service'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; -import { ExceptionDialogRepetitionOptionsComponent, RepetitionConfig } from './exception-repetition-options.component'; +import { ExceptionDialogRepetitionOptionsComponent } from './exception-repetition-options.component'; @Component({ standalone: true, diff --git a/ui/src/app/facility/schedule/exception-repetition-options.component.ts b/ui/src/app/facility/schedule/exception-repetition-options.component.ts index 844c2f5ca..4d5d6350d 100644 --- a/ui/src/app/facility/schedule/exception-repetition-options.component.ts +++ b/ui/src/app/facility/schedule/exception-repetition-options.component.ts @@ -8,18 +8,10 @@ import { FormsModule } from '@angular/forms'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { DateTime } from 'luxon'; +import { RepetitionConfig } from 'src/app/facility/facility.model'; import { DateTimePickerComponent } from 'src/app/shared/date/date-time-picker.component'; import { DateTimeService, REPEAT_OPTION } from 'src/app/shared/date/date.service'; -export type RepetitionConfig = { - start: Date; - end: Date; - weekdays: { ord: number; name: string }[]; - dayOfMonth?: number; - monthlyOrdinal?: { name: string; ord: number }; - monthlyWeekday?: { name: string; ord: number }; - yearlyMonth?: { name: string; ord: number }; -}; enum ORDINAL { First = 'FIRST', Second = 'SECOND', diff --git a/ui/src/app/facility/schedule/maintenance-period-dialog.component.ts b/ui/src/app/facility/schedule/maintenance-period-dialog.component.ts index ac2d5f6f7..791453bcc 100644 --- a/ui/src/app/facility/schedule/maintenance-period-dialog.component.ts +++ b/ui/src/app/facility/schedule/maintenance-period-dialog.component.ts @@ -7,7 +7,7 @@ import { FormsModule } from '@angular/forms'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { MaintenancePeriod } from 'src/app/exam/exam.model'; +import { MaintenancePeriod } from 'src/app/facility/facility.model'; import { DateTimePickerComponent } from 'src/app/shared/date/date-time-picker.component'; @Component({ diff --git a/ui/src/app/facility/schedule/opening-hours.component.ts b/ui/src/app/facility/schedule/opening-hours.component.ts index 9428c0585..9e7fd0ae0 100644 --- a/ui/src/app/facility/schedule/opening-hours.component.ts +++ b/ui/src/app/facility/schedule/opening-hours.component.ts @@ -15,8 +15,8 @@ import { import { TranslateService } from '@ngx-translate/core'; import { areIntervalsOverlapping, formatISO, setDayOfYear } from 'date-fns'; import { ToastrService } from 'ngx-toastr'; +import { DefaultWorkingHoursWithEditing } from 'src/app/facility/facility.model'; import { RoomService } from 'src/app/facility/rooms/room.service'; -import { DefaultWorkingHoursWithEditing } from 'src/app/facility/rooms/rooms.component'; import { DefaultWorkingHours, ExamRoom } from 'src/app/reservation/reservation.model'; import { DateTimeService } from 'src/app/shared/date/date.service'; interface RoomWithAddressVisibility extends ExamRoom { diff --git a/ui/src/app/facility/schedule/starting-time.component.ts b/ui/src/app/facility/schedule/starting-time.component.ts index 19fcff276..ef50894ab 100644 --- a/ui/src/app/facility/schedule/starting-time.component.ts +++ b/ui/src/app/facility/schedule/starting-time.component.ts @@ -9,7 +9,7 @@ import { FormsModule } from '@angular/forms'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { format, parseISO } from 'date-fns'; -import type { WorkingHour } from 'src/app/facility/rooms/room.service'; +import { WorkingHour } from 'src/app/facility/facility.model'; import { RoomService } from 'src/app/facility/rooms/room.service'; @Component({ diff --git a/ui/src/app/maturity/language-inspections.component.ts b/ui/src/app/maturity/language-inspections.component.ts index f52bd162e..b32018561 100644 --- a/ui/src/app/maturity/language-inspections.component.ts +++ b/ui/src/app/maturity/language-inspections.component.ts @@ -9,20 +9,10 @@ import { addDays } from 'date-fns'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { LanguageService } from 'src/app/shared/language/language.service'; -import type { QueryParams } from './language-inspections.service'; import { LanguageInspectionService } from './language-inspections.service'; import { ReviewedInspectionsComponent } from './listing/reviewed-inspections.component'; import { UnfinishedInspectionsComponent } from './listing/unfinished-inspections.component'; -import type { LanguageInspection } from './maturity.model'; - -export interface LanguageInspectionData extends LanguageInspection { - ownerAggregate: string; - studentName: string; - studentNameAggregate: string; - inspectorName: string; - inspectorNameAggregate: string; - answerLanguage?: string; -} +import type { LanguageInspection, LanguageInspectionData, QueryParams } from './maturity.model'; @Component({ selector: 'xm-language-inspections', diff --git a/ui/src/app/maturity/language-inspections.service.ts b/ui/src/app/maturity/language-inspections.service.ts index bd55d3487..0c7920069 100644 --- a/ui/src/app/maturity/language-inspections.service.ts +++ b/ui/src/app/maturity/language-inspections.service.ts @@ -12,13 +12,7 @@ import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { InspectionStatementDialogComponent } from './dialogs/inspection-statement-dialog.component'; -import type { LanguageInspection } from './maturity.model'; - -export interface QueryParams { - text?: string; - start?: number; - end?: number; -} +import type { LanguageInspection, QueryParams } from './maturity.model'; @Injectable({ providedIn: 'root' }) export class LanguageInspectionService { diff --git a/ui/src/app/maturity/listing/reviewed-inspections.component.ts b/ui/src/app/maturity/listing/reviewed-inspections.component.ts index 5cdb7c5b7..db2ea2e78 100644 --- a/ui/src/app/maturity/listing/reviewed-inspections.component.ts +++ b/ui/src/app/maturity/listing/reviewed-inspections.component.ts @@ -9,8 +9,8 @@ import { FormsModule } from '@angular/forms'; import { RouterLink } from '@angular/router'; import { NgbCollapse, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import type { LanguageInspectionData } from 'src/app/maturity/language-inspections.component'; import { LanguageInspectionService } from 'src/app/maturity/language-inspections.service'; +import { LanguageInspectionData } from 'src/app/maturity/maturity.model'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; import { PageFillPipe } from 'src/app/shared/paginator/page-fill.pipe'; diff --git a/ui/src/app/maturity/listing/unfinished-inspections.component.ts b/ui/src/app/maturity/listing/unfinished-inspections.component.ts index 3f7170681..83fa4e1e2 100644 --- a/ui/src/app/maturity/listing/unfinished-inspections.component.ts +++ b/ui/src/app/maturity/listing/unfinished-inspections.component.ts @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + import { DatePipe } from '@angular/common'; import type { OnChanges } from '@angular/core'; import { Component, Input } from '@angular/core'; @@ -5,19 +9,14 @@ import { FormsModule } from '@angular/forms'; import { RouterLink } from '@angular/router'; import { NgbCollapse, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; -import type { LanguageInspectionData } from 'src/app/maturity/language-inspections.component'; import { LanguageInspectionService } from 'src/app/maturity/language-inspections.service'; -import type { LanguageInspection } from 'src/app/maturity/maturity.model'; -import type { User } from 'src/app/session/session.service'; +import type { LanguageInspection, LanguageInspectionData } from 'src/app/maturity/maturity.model'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; import { TableSortComponent } from 'src/app/shared/sorting/table-sort.component'; -// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium -// -// SPDX-License-Identifier: EUPL-1.2 - @Component({ selector: 'xm-unfinished-inspections', templateUrl: './unfinished-inspections.component.html', diff --git a/ui/src/app/maturity/maturity.model.ts b/ui/src/app/maturity/maturity.model.ts index 6960504eb..13f311873 100644 --- a/ui/src/app/maturity/maturity.model.ts +++ b/ui/src/app/maturity/maturity.model.ts @@ -2,8 +2,9 @@ // // SPDX-License-Identifier: EUPL-1.2 -import type { Attachment, Exam } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { Exam } from 'src/app/exam/exam.model'; +import type { User } from 'src/app/session/session.model'; +import { Attachment } from 'src/app/shared/attachment/attachment.model'; export interface LanguageInspection { id: number; exam: Exam; @@ -16,3 +17,18 @@ export interface LanguageInspection { created: Date; statement: { attachment?: Attachment; comment?: string }; } + +export interface LanguageInspectionData extends LanguageInspection { + ownerAggregate: string; + studentName: string; + studentNameAggregate: string; + inspectorName: string; + inspectorNameAggregate: string; + answerLanguage?: string; +} + +export interface QueryParams { + text?: string; + start?: number; + end?: number; +} diff --git a/ui/src/app/maturity/reporting/maturity-reporting.component.ts b/ui/src/app/maturity/reporting/maturity-reporting.component.ts index 5817caa95..83f05e4a5 100644 --- a/ui/src/app/maturity/reporting/maturity-reporting.component.ts +++ b/ui/src/app/maturity/reporting/maturity-reporting.component.ts @@ -9,13 +9,14 @@ import { FormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; import { formatISO, startOfMonth } from 'date-fns'; import { range } from 'ramda'; -import type { Attachment } from 'src/app/exam/exam.model'; import { LanguageInspectionService } from 'src/app/maturity/language-inspections.service'; import type { LanguageInspection } from 'src/app/maturity/maturity.model'; +import { Attachment } from 'src/app/shared/attachment/attachment.model'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; @Component({ diff --git a/ui/src/app/navigation/navigation.component.ts b/ui/src/app/navigation/navigation.component.ts index d61764224..eab85b587 100644 --- a/ui/src/app/navigation/navigation.component.ts +++ b/ui/src/app/navigation/navigation.component.ts @@ -11,9 +11,9 @@ import { ToastrService } from 'ngx-toastr'; import { Subject, forkJoin } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ExaminationStatusService } from 'src/app/examination/examination-status.service'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; -import type { Link } from './navigation.service'; +import type { Link } from './navigation.model'; import { NavigationService } from './navigation.service'; @Component({ diff --git a/ui/src/app/navigation/navigation.model.ts b/ui/src/app/navigation/navigation.model.ts new file mode 100644 index 000000000..bbe0eda61 --- /dev/null +++ b/ui/src/app/navigation/navigation.model.ts @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +export interface Link { + route: string; + visible: boolean; + name: string; + iconSvg?: string; + iconPng?: string; + submenu: { hidden: boolean; items: Link[] }; +} diff --git a/ui/src/app/navigation/navigation.service.ts b/ui/src/app/navigation/navigation.service.ts index a13542832..7bd80ff22 100644 --- a/ui/src/app/navigation/navigation.service.ts +++ b/ui/src/app/navigation/navigation.service.ts @@ -5,17 +5,9 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; - -export interface Link { - route: string; - visible: boolean; - name: string; - iconSvg?: string; - iconPng?: string; - submenu: { hidden: boolean; items: Link[] }; -} +import { Link } from './navigation.model'; @Injectable({ providedIn: 'root' }) export class NavigationService { diff --git a/ui/src/app/question/basequestion/claim-choice.component.ts b/ui/src/app/question/basequestion/claim-choice.component.ts index e48c020e1..0f243e0fd 100644 --- a/ui/src/app/question/basequestion/claim-choice.component.ts +++ b/ui/src/app/question/basequestion/claim-choice.component.ts @@ -6,8 +6,8 @@ import { NgClass, UpperCasePipe } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; -import type { MultipleChoiceOption, Question } from 'src/app/exam/exam.model'; -import { QuestionDraft, QuestionService } from 'src/app/question/question.service'; +import { MultipleChoiceOption, Question, QuestionDraft } from 'src/app/question/question.model'; +import { QuestionService } from 'src/app/question/question.service'; import { FixedPrecisionValidatorDirective } from 'src/app/shared/validation/fixed-precision.directive'; @Component({ diff --git a/ui/src/app/question/basequestion/essay.component.ts b/ui/src/app/question/basequestion/essay.component.ts index 4250aba2c..59a21880c 100644 --- a/ui/src/app/question/basequestion/essay.component.ts +++ b/ui/src/app/question/basequestion/essay.component.ts @@ -5,8 +5,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; -import type { Question } from 'src/app/exam/exam.model'; -import { QuestionDraft } from 'src/app/question/question.service'; +import { Question, QuestionDraft } from 'src/app/question/question.model'; @Component({ selector: 'xm-essay-editor', diff --git a/ui/src/app/question/basequestion/multiple-choice-option.component.ts b/ui/src/app/question/basequestion/multiple-choice-option.component.ts index 89be336b7..ac6816824 100644 --- a/ui/src/app/question/basequestion/multiple-choice-option.component.ts +++ b/ui/src/app/question/basequestion/multiple-choice-option.component.ts @@ -7,8 +7,8 @@ import { Component, Input } from '@angular/core'; import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { MultipleChoiceOption, Question } from 'src/app/exam/exam.model'; -import { QuestionDraft, QuestionService } from 'src/app/question/question.service'; +import { MultipleChoiceOption, Question, QuestionDraft } from 'src/app/question/question.model'; +import { QuestionService } from 'src/app/question/question.service'; @Component({ selector: 'xm-mc-option-editor', diff --git a/ui/src/app/question/basequestion/multiple-choice.component.ts b/ui/src/app/question/basequestion/multiple-choice.component.ts index 436335607..cf2d94e63 100644 --- a/ui/src/app/question/basequestion/multiple-choice.component.ts +++ b/ui/src/app/question/basequestion/multiple-choice.component.ts @@ -6,8 +6,8 @@ import { UpperCasePipe } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { MultipleChoiceOption, Question } from 'src/app/exam/exam.model'; -import { QuestionDraft, QuestionService } from 'src/app/question/question.service'; +import { MultipleChoiceOption, Question, QuestionDraft } from 'src/app/question/question.model'; +import { QuestionService } from 'src/app/question/question.service'; import { MultipleChoiceOptionEditorComponent } from './multiple-choice-option.component'; import { WeightedMultipleChoiceOptionEditorComponent } from './weighted-multiple-choice-option.component'; diff --git a/ui/src/app/question/basequestion/question-body.component.ts b/ui/src/app/question/basequestion/question-body.component.ts index ca73f4415..32ae64eb7 100644 --- a/ui/src/app/question/basequestion/question-body.component.ts +++ b/ui/src/app/question/basequestion/question-body.component.ts @@ -11,13 +11,13 @@ import { TranslateModule } from '@ngx-translate/core'; import type { Observable } from 'rxjs'; import { from } from 'rxjs'; import { debounceTime, distinctUntilChanged, exhaustMap, map } from 'rxjs/operators'; -import type { ExamSectionQuestion, ReverseQuestion, Tag } from 'src/app/exam/exam.model'; import { QuestionBasicInfoComponent } from 'src/app/question/question-basic-info.component'; import { QuestionUsageComponent } from 'src/app/question/question-usage.component'; -import type { QuestionDraft } from 'src/app/question/question.service'; +import type { QuestionDraft } from 'src/app/question/question.model'; +import { ExamSectionQuestion, ReverseQuestion, Tag } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { TagPickerComponent } from 'src/app/question/tags/tag-picker.component'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; diff --git a/ui/src/app/question/basequestion/question.component.ts b/ui/src/app/question/basequestion/question.component.ts index 6c2bbe505..7a52a88a5 100644 --- a/ui/src/app/question/basequestion/question.component.ts +++ b/ui/src/app/question/basequestion/question.component.ts @@ -8,12 +8,12 @@ import { ActivatedRoute, Router } from '@angular/router'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExamSectionQuestion, Question, ReverseQuestion } from 'src/app/exam/exam.model'; import { CanComponentDeactivate } from 'src/app/question/has-unsaved-changes.quard'; import { QuestionPreviewDialogComponent } from 'src/app/question/preview/question-preview-dialog.component'; -import type { QuestionDraft } from 'src/app/question/question.service'; +import type { QuestionDraft } from 'src/app/question/question.model'; +import { ExamSectionQuestion, Question, ReverseQuestion } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { QuestionBodyComponent } from './question-body.component'; diff --git a/ui/src/app/question/basequestion/weighted-multiple-choice-option.component.ts b/ui/src/app/question/basequestion/weighted-multiple-choice-option.component.ts index c7045f8ed..b9f3d479d 100644 --- a/ui/src/app/question/basequestion/weighted-multiple-choice-option.component.ts +++ b/ui/src/app/question/basequestion/weighted-multiple-choice-option.component.ts @@ -7,8 +7,7 @@ import { Component, Input } from '@angular/core'; import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { MultipleChoiceOption, Question } from 'src/app/exam/exam.model'; -import { QuestionDraft } from 'src/app/question/question.service'; +import { MultipleChoiceOption, Question, QuestionDraft } from 'src/app/question/question.model'; import { FixedPrecisionValidatorDirective } from 'src/app/shared/validation/fixed-precision.directive'; @Component({ diff --git a/ui/src/app/question/examquestion/base-question-editor.component.ts b/ui/src/app/question/examquestion/base-question-editor.component.ts index 856f5cfd9..28931acdd 100644 --- a/ui/src/app/question/examquestion/base-question-editor.component.ts +++ b/ui/src/app/question/examquestion/base-question-editor.component.ts @@ -5,9 +5,9 @@ import { Component, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; -import type { ExamSectionQuestion, Question } from 'src/app/exam/exam.model'; import { QuestionComponent } from 'src/app/question/basequestion/question.component'; -import type { QuestionDraft } from 'src/app/question/question.service'; +import type { QuestionDraft } from 'src/app/question/question.model'; +import { ExamSectionQuestion, Question } from 'src/app/question/question.model'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; @Component({ diff --git a/ui/src/app/question/examquestion/claim-choice.component.ts b/ui/src/app/question/examquestion/claim-choice.component.ts index 06f4d7614..c873fb667 100644 --- a/ui/src/app/question/examquestion/claim-choice.component.ts +++ b/ui/src/app/question/examquestion/claim-choice.component.ts @@ -7,7 +7,7 @@ import { Component, computed, input, output } from '@angular/core'; import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import { ExamSectionQuestionOption } from 'src/app/exam/exam.model'; +import { ExamSectionQuestionOption } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; @Component({ diff --git a/ui/src/app/question/examquestion/exam-question-editor.component.ts b/ui/src/app/question/examquestion/exam-question-editor.component.ts index ca7a7ce1e..09d5c7f6c 100644 --- a/ui/src/app/question/examquestion/exam-question-editor.component.ts +++ b/ui/src/app/question/examquestion/exam-question-editor.component.ts @@ -5,7 +5,7 @@ import { Component, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; -import type { ExamSectionQuestion, Question } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion, Question } from 'src/app/question/question.model'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { ExamQuestionComponent } from './exam-question.component'; diff --git a/ui/src/app/question/examquestion/exam-question.component.ts b/ui/src/app/question/examquestion/exam-question.component.ts index 9d1b0c39c..4a5fdb785 100644 --- a/ui/src/app/question/examquestion/exam-question.component.ts +++ b/ui/src/app/question/examquestion/exam-question.component.ts @@ -9,15 +9,15 @@ import { FormsModule, NgForm } from '@angular/forms'; import { NgbModal, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; +import { QuestionPreviewDialogComponent } from 'src/app/question/preview/question-preview-dialog.component'; +import { QuestionBasicInfoComponent } from 'src/app/question/question-basic-info.component'; +import { QuestionUsageComponent } from 'src/app/question/question-usage.component'; import type { ExamSectionQuestion, ExamSectionQuestionOption, Question, ReverseQuestion, -} from 'src/app/exam/exam.model'; -import { QuestionPreviewDialogComponent } from 'src/app/question/preview/question-preview-dialog.component'; -import { QuestionBasicInfoComponent } from 'src/app/question/question-basic-info.component'; -import { QuestionUsageComponent } from 'src/app/question/question-usage.component'; +} from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; diff --git a/ui/src/app/question/examquestion/multichoice.component.ts b/ui/src/app/question/examquestion/multichoice.component.ts index c2d0c3a1f..c630650f1 100644 --- a/ui/src/app/question/examquestion/multichoice.component.ts +++ b/ui/src/app/question/examquestion/multichoice.component.ts @@ -8,7 +8,7 @@ import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import { ExamSectionQuestionOption } from 'src/app/exam/exam.model'; +import { ExamSectionQuestionOption } from 'src/app/question/question.model'; @Component({ selector: 'xm-eq-unweighted-mc', diff --git a/ui/src/app/question/examquestion/weighted-multichoice.component.ts b/ui/src/app/question/examquestion/weighted-multichoice.component.ts index 6821209d5..db4ad0a46 100644 --- a/ui/src/app/question/examquestion/weighted-multichoice.component.ts +++ b/ui/src/app/question/examquestion/weighted-multichoice.component.ts @@ -8,7 +8,7 @@ import { ControlContainer, FormsModule, NgForm } from '@angular/forms'; import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import { ExamSectionQuestionOption } from 'src/app/exam/exam.model'; +import { ExamSectionQuestionOption } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; @Component({ diff --git a/ui/src/app/question/library/library.component.ts b/ui/src/app/question/library/library.component.ts index 9e1bc30cc..c519b332d 100644 --- a/ui/src/app/question/library/library.component.ts +++ b/ui/src/app/question/library/library.component.ts @@ -8,8 +8,8 @@ import { NgbDropdownModule, NgbModal, NgbPopoverModule } from '@ng-bootstrap/ng- import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import { from, noop, tap } from 'rxjs'; -import type { Question, Tag } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import { Question, Tag } from 'src/app/question/question.model'; +import type { User } from 'src/app/session/session.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/question/library/library.service.ts b/ui/src/app/question/library/library.service.ts index de8c7068e..ce1ec013b 100644 --- a/ui/src/app/question/library/library.service.ts +++ b/ui/src/app/question/library/library.service.ts @@ -7,19 +7,12 @@ import { Inject, Injectable } from '@angular/core'; import { SESSION_STORAGE, WebStorageService } from 'ngx-webstorage-service'; import type { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import type { Course, Exam, ExamSection, ReverseQuestion, Tag } from 'src/app/exam/exam.model'; +import type { Course, Exam, ExamSection } from 'src/app/exam/exam.model'; +import { LibraryQuestion, Tag } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; -import { User } from 'src/app/session/session.service'; +import { User } from 'src/app/session/session.model'; import { UserService } from 'src/app/shared/user/user.service'; -export interface LibraryQuestion extends ReverseQuestion { - icon: string; - displayedMaxScore: number | string; - typeOrd: number; - ownerAggregate: string; - allowedToRemove: boolean; -} - @Injectable({ providedIn: 'root' }) export class LibraryService { constructor( diff --git a/ui/src/app/question/library/owners/library-owners-dialog.component.ts b/ui/src/app/question/library/owners/library-owners-dialog.component.ts index c1a6a0dc6..8b16982bc 100644 --- a/ui/src/app/question/library/owners/library-owners-dialog.component.ts +++ b/ui/src/app/question/library/owners/library-owners-dialog.component.ts @@ -11,7 +11,7 @@ import type { Observable } from 'rxjs'; import { throwError } from 'rxjs'; import { catchError, debounceTime, distinctUntilChanged, map, take } from 'rxjs/operators'; import { QuestionService } from 'src/app/question/question.service'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { UserService } from 'src/app/shared/user/user.service'; @Component({ diff --git a/ui/src/app/question/library/results/library-results.component.ts b/ui/src/app/question/library/results/library-results.component.ts index 3a29e3840..cf0b96066 100644 --- a/ui/src/app/question/library/results/library-results.component.ts +++ b/ui/src/app/question/library/results/library-results.component.ts @@ -11,10 +11,9 @@ import { RouterLink } from '@angular/router'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { Question } from 'src/app/exam/exam.model'; -import type { LibraryQuestion } from 'src/app/question/library/library.service'; import { LibraryService } from 'src/app/question/library/library.service'; -import type { User } from 'src/app/session/session.service'; +import { LibraryQuestion, Question } from 'src/app/question/question.model'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; diff --git a/ui/src/app/question/library/search/library-search.component.ts b/ui/src/app/question/library/search/library-search.component.ts index 6a3da30c4..dbd5d5357 100644 --- a/ui/src/app/question/library/search/library-search.component.ts +++ b/ui/src/app/question/library/search/library-search.component.ts @@ -11,10 +11,10 @@ import { TranslateModule } from '@ngx-translate/core'; import { DateTime } from 'luxon'; import type { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; -import type { Course, Exam, ExamSection, Tag } from 'src/app/exam/exam.model'; -import type { LibraryQuestion } from 'src/app/question/library/library.service'; +import type { Course, Exam, ExamSection } from 'src/app/exam/exam.model'; import { LibraryService } from 'src/app/question/library/library.service'; -import type { User } from 'src/app/session/session.service'; +import { LibraryQuestion, Tag } from 'src/app/question/question.model'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { CourseCodeService } from 'src/app/shared/miscellaneous/course-code.service'; import { UserService } from 'src/app/shared/user/user.service'; diff --git a/ui/src/app/question/library/tags/library-tags-dialog.component.ts b/ui/src/app/question/library/tags/library-tags-dialog.component.ts index 86506e486..e5c5fffb1 100644 --- a/ui/src/app/question/library/tags/library-tags-dialog.component.ts +++ b/ui/src/app/question/library/tags/library-tags-dialog.component.ts @@ -10,8 +10,8 @@ import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { throwError } from 'rxjs'; import { catchError, debounceTime, distinctUntilChanged, map, take } from 'rxjs/operators'; -import { Tag } from 'src/app/exam/exam.model'; import { LibraryService } from 'src/app/question/library/library.service'; +import { Tag } from 'src/app/question/question.model'; @Component({ template: ` diff --git a/ui/src/app/question/picker/question-picker.component.ts b/ui/src/app/question/picker/question-picker.component.ts index f66cc5e7a..4fac98d9f 100644 --- a/ui/src/app/question/picker/question-picker.component.ts +++ b/ui/src/app/question/picker/question-picker.component.ts @@ -7,9 +7,10 @@ import { Component, Input } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExamSection, Question } from 'src/app/exam/exam.model'; +import type { ExamSection } from 'src/app/exam/exam.model'; import { LibraryResultsComponent } from 'src/app/question/library/results/library-results.component'; import { LibrarySearchComponent } from 'src/app/question/library/search/library-search.component'; +import { Question } from 'src/app/question/question.model'; @Component({ selector: 'xm-question-selector', diff --git a/ui/src/app/question/preview/question-preview-dialog.component.ts b/ui/src/app/question/preview/question-preview-dialog.component.ts index 6dae6066c..23fbecb54 100644 --- a/ui/src/app/question/preview/question-preview-dialog.component.ts +++ b/ui/src/app/question/preview/question-preview-dialog.component.ts @@ -6,9 +6,9 @@ import { HttpClient } from '@angular/common/http'; import { Component, Input, OnInit } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import { Question } from 'src/app/exam/exam.model'; import { ExaminationQuestion } from 'src/app/examination/examination.model'; import { ExaminationQuestionComponent } from 'src/app/examination/question/examination-question.component'; +import { Question } from 'src/app/question/question.model'; @Component({ template: ` diff --git a/ui/src/app/question/question.model.ts b/ui/src/app/question/question.model.ts new file mode 100644 index 000000000..3012683f2 --- /dev/null +++ b/ui/src/app/question/question.model.ts @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +import { ReverseExamSection } from 'src/app/exam/exam.model'; +import { User } from 'src/app/session/session.model'; +import { Attachment } from 'src/app/shared/attachment/attachment.model'; + +export interface ReverseExamSectionQuestion extends ExamSectionQuestion { + examSection: ReverseExamSection; +} + +export interface ReverseQuestion extends Question { + examSectionQuestions: ReverseExamSectionQuestion[]; +} + +export interface Tag { + id?: number; + name: string; + creator?: User; + questions: Question[]; +} + +export interface Question { + id: number; + question: string; + creator?: User; + type: string; + attachment?: Attachment; + options: MultipleChoiceOption[]; + tags: Tag[]; + questionOwners: User[]; + parent?: Question; + state: string; + defaultMaxScore?: number; + modifier?: User; + modified?: Date; + shared?: boolean; + defaultAnswerInstructions?: string; + defaultEvaluationCriteria?: string; + defaultExpectedWordCount?: number; + defaultEvaluationType?: string; +} + +export type QuestionDraft = Omit & { id: undefined }; +export type QuestionAmounts = { + accepted: number; + rejected: number; + hasEssays: boolean; +}; + +export interface LibraryQuestion extends ReverseQuestion { + icon: string; + displayedMaxScore: number | string; + typeOrd: number; + ownerAggregate: string; + allowedToRemove: boolean; +} + +export interface EssayAnswer { + id?: number; + evaluatedScore?: number; + answer?: string; + objectVersion?: number; + attachment?: Attachment; +} + +export interface MultipleChoiceOption { + id?: number; + option: string; + correctOption: boolean; + defaultScore: number; + claimChoiceType?: string; +} + +export enum ClaimChoiceOptionType { + CorrectOption = 'CorrectOption', + IncorrectOption = 'IncorrectOption', + SkipOption = 'SkipOption', +} + +export interface ExamSectionQuestionOption { + id?: number; + score: number; + answered: boolean; + option: MultipleChoiceOption; +} + +export interface ClozeTestAnswer { + id: number; + score?: { correctAnswers: number; incorrectAnswers: number }; + maxScore: number; + answer: string; + objectVersion: number; + question: string; +} + +export interface ExamSectionQuestion { + id: number; + question: Question; + evaluationType?: string; + forcedScore: number | null; + maxScore: number; + essayAnswer?: EssayAnswer; + clozeTestAnswer?: ClozeTestAnswer; + options: ExamSectionQuestionOption[]; + answerInstructions: string; + evaluationCriteria: string; + expectedWordCount?: number; + sequenceNumber: number; + expanded: boolean; + derivedMaxScore?: number; + derivedAssessedScore?: number; +} diff --git a/ui/src/app/question/question.service.ts b/ui/src/app/question/question.service.ts index e76add77d..4cc3ec483 100644 --- a/ui/src/app/question/question.service.ts +++ b/ui/src/app/question/question.service.ts @@ -8,26 +8,20 @@ import { TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import type { - Exam, - ExamSection, +import type { Exam, ExamSection } from 'src/app/exam/exam.model'; +import { SessionService } from 'src/app/session/session.service'; +import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; +import { FileService } from 'src/app/shared/file/file.service'; +import { isNumber } from 'src/app/shared/miscellaneous/helpers'; +import { ExamSectionQuestion, ExamSectionQuestionOption, MultipleChoiceOption, Question, + QuestionAmounts, + QuestionDraft, ReverseQuestion, -} from 'src/app/exam/exam.model'; -import { SessionService } from 'src/app/session/session.service'; -import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; -import { FileService } from 'src/app/shared/file/file.service'; -import { isNumber } from 'src/app/shared/miscellaneous/helpers'; - -export type QuestionDraft = Omit & { id: undefined }; -export type QuestionAmounts = { - accepted: number; - rejected: number; - hasEssays: boolean; -}; +} from './question.model'; @Injectable({ providedIn: 'root' }) export class QuestionService { diff --git a/ui/src/app/question/tags/tag-picker.component.ts b/ui/src/app/question/tags/tag-picker.component.ts index c97096c3f..c0e3c0c65 100644 --- a/ui/src/app/question/tags/tag-picker.component.ts +++ b/ui/src/app/question/tags/tag-picker.component.ts @@ -10,9 +10,9 @@ import { TranslateModule } from '@ngx-translate/core'; import type { Observable } from 'rxjs'; import { from } from 'rxjs'; import { debounceTime, distinctUntilChanged, exhaustMap, map } from 'rxjs/operators'; -import type { Question, Tag } from 'src/app/exam/exam.model'; -import { QuestionDraft } from 'src/app/question/question.service'; -import { SessionService, User } from 'src/app/session/session.service'; +import { Question, QuestionDraft, Tag } from 'src/app/question/question.model'; +import { User } from 'src/app/session/session.model'; +import { SessionService } from 'src/app/session/session.service'; @Component({ selector: 'xm-tag-picker', diff --git a/ui/src/app/reservation/admin/change-machine-dialog.component.ts b/ui/src/app/reservation/admin/change-machine-dialog.component.ts index 32eb63bab..825f7341b 100644 --- a/ui/src/app/reservation/admin/change-machine-dialog.component.ts +++ b/ui/src/app/reservation/admin/change-machine-dialog.component.ts @@ -9,7 +9,8 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import type { ExamMachine, Reservation } from 'src/app/reservation/reservation.model'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; @Component({ selector: 'xm-change-machine-dialog', diff --git a/ui/src/app/reservation/reservation.model.ts b/ui/src/app/reservation/reservation.model.ts index 60c085263..990ec9072 100644 --- a/ui/src/app/reservation/reservation.model.ts +++ b/ui/src/app/reservation/reservation.model.ts @@ -3,8 +3,8 @@ // SPDX-License-Identifier: EUPL-1.2 import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; -import type { Address, WorkingHour } from 'src/app/facility/rooms/room.service'; -import type { User } from 'src/app/session/session.service'; +import { Address, WorkingHour } from 'src/app/facility/facility.model'; +import type { User } from 'src/app/session/session.model'; export type DefaultWorkingHours = { id?: number; diff --git a/ui/src/app/reservation/reservations.component.ts b/ui/src/app/reservation/reservations.component.ts index 8a0d5582f..b35b48401 100644 --- a/ui/src/app/reservation/reservations.component.ts +++ b/ui/src/app/reservation/reservations.component.ts @@ -14,13 +14,14 @@ import { Observable, forkJoin, from, of } from 'rxjs'; import { debounceTime, distinctUntilChanged, exhaustMap, map } from 'rxjs/operators'; import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; import type { CollaborativeExam, Exam, ExamImpl, Implementation } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; import { DatePickerComponent } from 'src/app/shared/date/date-picker.component'; import { isObject } from 'src/app/shared/miscellaneous/helpers'; -import { DropdownSelectComponent, Option } from 'src/app/shared/select/dropdown-select.component'; +import { DropdownSelectComponent } from 'src/app/shared/select/dropdown-select.component'; +import { Option } from 'src/app/shared/select/select.model'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; import { ReservationDetailsComponent } from './reservation-details.component'; import type { ExamMachine, ExamRoom, Reservation } from './reservation.model'; diff --git a/ui/src/app/review/assessment/assessment.component.ts b/ui/src/app/review/assessment/assessment.component.ts index 4b9c13279..e27836207 100644 --- a/ui/src/app/review/assessment/assessment.component.ts +++ b/ui/src/app/review/assessment/assessment.component.ts @@ -8,12 +8,13 @@ import { ActivatedRoute, Router } from '@angular/router'; import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ClozeTestAnswer, ExamParticipation } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { ExamService } from 'src/app/exam/exam.service'; import type { Examination } from 'src/app/examination/examination.model'; -import type { QuestionAmounts } from 'src/app/question/question.service'; +import type { QuestionAmounts } from 'src/app/question/question.model'; +import { ClozeTestAnswer } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/review/assessment/assessment.service.ts b/ui/src/app/review/assessment/assessment.service.ts index ab4e22f62..b8c957f85 100644 --- a/ui/src/app/review/assessment/assessment.service.ts +++ b/ui/src/app/review/assessment/assessment.service.ts @@ -12,8 +12,10 @@ import type { Observable } from 'rxjs'; import { of, throwError } from 'rxjs'; import { catchError, switchMap, tap } from 'rxjs/operators'; import type { ReviewedExam } from 'src/app/enrolment/enrolment.model'; -import type { Exam, ExamLanguage, ExamSectionQuestion, Feedback } from 'src/app/exam/exam.model'; +import type { Exam, ExamLanguage } from 'src/app/exam/exam.model'; import { isRealGrade } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; +import { Feedback } from 'src/app/review/review.model'; import { SessionService } from 'src/app/session/session.service'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; @@ -29,7 +31,7 @@ type Payload = { additionalInfo: string; }; -export type Link = { +type Link = { fragments: string[]; params?: { [key: string]: unknown }; }; diff --git a/ui/src/app/review/assessment/collaborative-assessment.service.ts b/ui/src/app/review/assessment/collaborative-assessment.service.ts index 2ecdeebfd..21c70143c 100644 --- a/ui/src/app/review/assessment/collaborative-assessment.service.ts +++ b/ui/src/app/review/assessment/collaborative-assessment.service.ts @@ -10,7 +10,9 @@ import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { of } from 'rxjs'; import { map, tap } from 'rxjs/operators'; -import type { Exam, ExamParticipation, Feedback, SelectableGrade } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Exam, SelectableGrade } from 'src/app/exam/exam.model'; +import { Feedback } from 'src/app/review/review.model'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { AssessmentService } from './assessment.service'; diff --git a/ui/src/app/review/assessment/feedback/feedback.component.ts b/ui/src/app/review/assessment/feedback/feedback.component.ts index e42424f47..70c9c8239 100644 --- a/ui/src/app/review/assessment/feedback/feedback.component.ts +++ b/ui/src/app/review/assessment/feedback/feedback.component.ts @@ -9,12 +9,12 @@ import { FormsModule } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { NgbCollapse, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamParticipation } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; import type { Examination } from 'src/app/examination/examination.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import { CollaborativeAssesmentService } from 'src/app/review/assessment/collaborative-assessment.service'; +import { FileResult } from 'src/app/shared/attachment/attachment.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; -import type { FileResult } from 'src/app/shared/attachment/dialogs/attachment-picker.component'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; import { FileService } from 'src/app/shared/file/file.service'; diff --git a/ui/src/app/review/assessment/feedback/statement.component.ts b/ui/src/app/review/assessment/feedback/statement.component.ts index ea75432c5..3d6d3af17 100644 --- a/ui/src/app/review/assessment/feedback/statement.component.ts +++ b/ui/src/app/review/assessment/feedback/statement.component.ts @@ -11,8 +11,8 @@ import { TranslateModule } from '@ngx-translate/core'; import type { Exam } from 'src/app/exam/exam.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import { MaturityService } from 'src/app/review/assessment/maturity/maturity.service'; +import { FileResult } from 'src/app/shared/attachment/attachment.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; -import type { FileResult } from 'src/app/shared/attachment/dialogs/attachment-picker.component'; import { CKEditorComponent } from 'src/app/shared/ckeditor/ckeditor.component'; import { FileService } from 'src/app/shared/file/file.service'; diff --git a/ui/src/app/review/assessment/general/general-info.component.ts b/ui/src/app/review/assessment/general/general-info.component.ts index 7007105d3..ca7c52b2d 100644 --- a/ui/src/app/review/assessment/general/general-info.component.ts +++ b/ui/src/app/review/assessment/general/general-info.component.ts @@ -8,10 +8,10 @@ import { Component, Input, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { parseISO, roundToNearestMinutes } from 'date-fns'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; -import type { Exam, ExamParticipation } from 'src/app/exam/exam.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Exam } from 'src/app/exam/exam.model'; import type { Reservation } from 'src/app/reservation/reservation.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { DateTimeService } from 'src/app/shared/date/date.service'; @@ -19,7 +19,7 @@ import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { NoShowComponent } from './no-show.component'; import { ParticipationComponent } from './participation.component'; -export type Participation = Omit & { exam: Partial }; +type Participation = Omit & { exam: Partial }; @Component({ selector: 'xm-r-general-info', diff --git a/ui/src/app/review/assessment/general/participation.component.ts b/ui/src/app/review/assessment/general/participation.component.ts index 4488acbd7..e3ea3c5d5 100644 --- a/ui/src/app/review/assessment/general/participation.component.ts +++ b/ui/src/app/review/assessment/general/participation.component.ts @@ -6,7 +6,7 @@ import { DatePipe, LowerCasePipe, NgClass } from '@angular/common'; import { Component, Input } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamParticipation } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { SessionService } from 'src/app/session/session.service'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; diff --git a/ui/src/app/review/assessment/grading/grading.component.ts b/ui/src/app/review/assessment/grading/grading.component.ts index 1c4c37947..22fe5fcfd 100644 --- a/ui/src/app/review/assessment/grading/grading.component.ts +++ b/ui/src/app/review/assessment/grading/grading.component.ts @@ -11,14 +11,15 @@ import { ActivatedRoute } from '@angular/router'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { Exam, ExamLanguage, ExamParticipation, ExamType, SelectableGrade } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Exam, ExamLanguage, ExamType, SelectableGrade } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; import type { Examination } from 'src/app/examination/examination.model'; -import type { QuestionAmounts } from 'src/app/question/question.service'; +import type { QuestionAmounts } from 'src/app/question/question.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import { CollaborativeAssesmentService } from 'src/app/review/assessment/collaborative-assessment.service'; import { GradingBaseComponent } from 'src/app/review/assessment/common/grading-base.component'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { LanguageService } from 'src/app/shared/language/language.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; diff --git a/ui/src/app/review/assessment/grading/inspection.component.ts b/ui/src/app/review/assessment/grading/inspection.component.ts index ee8e4b1ca..df249bf36 100644 --- a/ui/src/app/review/assessment/grading/inspection.component.ts +++ b/ui/src/app/review/assessment/grading/inspection.component.ts @@ -9,7 +9,7 @@ import { FormsModule } from '@angular/forms'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import type { ExamInspection } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; @Component({ selector: 'xm-r-inspection', diff --git a/ui/src/app/review/assessment/grading/toolbar.component.ts b/ui/src/app/review/assessment/grading/toolbar.component.ts index 8d5b3d374..2e1b225ce 100644 --- a/ui/src/app/review/assessment/grading/toolbar.component.ts +++ b/ui/src/app/review/assessment/grading/toolbar.component.ts @@ -7,7 +7,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExamParticipation } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { ExamService } from 'src/app/exam/exam.service'; import type { Examination } from 'src/app/examination/examination.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; diff --git a/ui/src/app/review/assessment/maturity/grading.component.ts b/ui/src/app/review/assessment/maturity/grading.component.ts index 432531438..a6d06128f 100644 --- a/ui/src/app/review/assessment/maturity/grading.component.ts +++ b/ui/src/app/review/assessment/maturity/grading.component.ts @@ -13,7 +13,7 @@ import type { Exam } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import { GradingBaseComponent } from 'src/app/review/assessment/common/grading-base.component'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { LanguageService } from 'src/app/shared/language/language.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; diff --git a/ui/src/app/review/assessment/maturity/inspection-comments.component.ts b/ui/src/app/review/assessment/maturity/inspection-comments.component.ts index b6b3e199f..e590169c1 100644 --- a/ui/src/app/review/assessment/maturity/inspection-comments.component.ts +++ b/ui/src/app/review/assessment/maturity/inspection-comments.component.ts @@ -10,7 +10,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { from } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import type { Exam } from 'src/app/exam/exam.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { InspectionCommentDialogComponent } from './dialogs/inspection-comment-dialog.component'; @Component({ diff --git a/ui/src/app/review/assessment/print/printed-assessment.component.ts b/ui/src/app/review/assessment/print/printed-assessment.component.ts index 6ca217733..d9f4d69bd 100644 --- a/ui/src/app/review/assessment/print/printed-assessment.component.ts +++ b/ui/src/app/review/assessment/print/printed-assessment.component.ts @@ -8,14 +8,15 @@ import { AfterViewInit, Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { parseISO, roundToNearestMinutes } from 'date-fns'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; -import type { ClozeTestAnswer, Exam, ExamParticipation } from 'src/app/exam/exam.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import { Exam } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; -import type { QuestionAmounts } from 'src/app/question/question.service'; +import type { QuestionAmounts } from 'src/app/question/question.model'; +import { ClozeTestAnswer } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import type { Reservation } from 'src/app/reservation/reservation.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { DateTimeService } from 'src/app/shared/date/date.service'; diff --git a/ui/src/app/review/assessment/print/printed-cloze-test.component.ts b/ui/src/app/review/assessment/print/printed-cloze-test.component.ts index 20f78f0f0..16d3027f3 100644 --- a/ui/src/app/review/assessment/print/printed-cloze-test.component.ts +++ b/ui/src/app/review/assessment/print/printed-cloze-test.component.ts @@ -5,7 +5,7 @@ import { NgStyle } from '@angular/common'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { isNumber } from 'src/app/shared/miscellaneous/helpers'; diff --git a/ui/src/app/review/assessment/print/printed-essay.component.ts b/ui/src/app/review/assessment/print/printed-essay.component.ts index f4168c4aa..cb8f620c1 100644 --- a/ui/src/app/review/assessment/print/printed-essay.component.ts +++ b/ui/src/app/review/assessment/print/printed-essay.component.ts @@ -4,7 +4,7 @@ import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; diff --git a/ui/src/app/review/assessment/print/printed-multi-choice.component.ts b/ui/src/app/review/assessment/print/printed-multi-choice.component.ts index d367ace51..1fbe57bbf 100644 --- a/ui/src/app/review/assessment/print/printed-multi-choice.component.ts +++ b/ui/src/app/review/assessment/print/printed-multi-choice.component.ts @@ -5,7 +5,7 @@ import { NgClass, NgStyle } from '@angular/common'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { isNumber } from 'src/app/shared/miscellaneous/helpers'; diff --git a/ui/src/app/review/assessment/questions/claim-choice-answer.component.ts b/ui/src/app/review/assessment/questions/claim-choice-answer.component.ts index 3af7ed392..7c9395ffc 100644 --- a/ui/src/app/review/assessment/questions/claim-choice-answer.component.ts +++ b/ui/src/app/review/assessment/questions/claim-choice-answer.component.ts @@ -5,7 +5,7 @@ import { NgClass } from '@angular/common'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamSectionQuestion, ExamSectionQuestionOption } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion, ExamSectionQuestionOption } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; diff --git a/ui/src/app/review/assessment/questions/cloze-test.component.ts b/ui/src/app/review/assessment/questions/cloze-test.component.ts index b41aaec16..05ce08401 100644 --- a/ui/src/app/review/assessment/questions/cloze-test.component.ts +++ b/ui/src/app/review/assessment/questions/cloze-test.component.ts @@ -8,7 +8,8 @@ import { FormsModule, NgForm } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExamParticipation, ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; diff --git a/ui/src/app/review/assessment/questions/essay-question.component.ts b/ui/src/app/review/assessment/questions/essay-question.component.ts index fbbf6c2f4..f5f8b9d15 100644 --- a/ui/src/app/review/assessment/questions/essay-question.component.ts +++ b/ui/src/app/review/assessment/questions/essay-question.component.ts @@ -9,8 +9,9 @@ import { ActivatedRoute } from '@angular/router'; import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { Exam, ExamParticipation, ExamSectionQuestion } from 'src/app/exam/exam.model'; -import type { ExaminationQuestion } from 'src/app/examination/examination.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Exam } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import type { ReviewQuestion } from 'src/app/review/review.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; @@ -109,7 +110,7 @@ export class EssayQuestionComponent implements OnInit { insertEssayScore = () => { if (this.collaborative) { this.Assessment.saveCollaborativeEssayScore$( - this.sectionQuestion as ExaminationQuestion, + this.sectionQuestion, this.id, this.ref, this.participation._rev as string, @@ -118,7 +119,7 @@ export class EssayQuestionComponent implements OnInit { this.scored.emit(resp.rev); }); } else { - this.Assessment.saveEssayScore$(this.sectionQuestion as ExaminationQuestion).subscribe(() => { + this.Assessment.saveEssayScore$(this.sectionQuestion).subscribe(() => { this.toast.info(this.translate.instant('i18n_graded')); this.scored.emit(); }); diff --git a/ui/src/app/review/assessment/questions/multi-choice-answer.component.ts b/ui/src/app/review/assessment/questions/multi-choice-answer.component.ts index 53c25ff21..02d4335ae 100644 --- a/ui/src/app/review/assessment/questions/multi-choice-answer.component.ts +++ b/ui/src/app/review/assessment/questions/multi-choice-answer.component.ts @@ -4,7 +4,7 @@ import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamSectionQuestion } from 'src/app/exam/exam.model'; +import type { ExamSectionQuestion } from 'src/app/question/question.model'; import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; diff --git a/ui/src/app/review/assessment/questions/multi-choice-question.component.ts b/ui/src/app/review/assessment/questions/multi-choice-question.component.ts index e8b0f07b9..487c94f65 100644 --- a/ui/src/app/review/assessment/questions/multi-choice-question.component.ts +++ b/ui/src/app/review/assessment/questions/multi-choice-question.component.ts @@ -8,7 +8,8 @@ import { FormsModule, NgForm } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; -import type { ExamParticipation, ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; diff --git a/ui/src/app/review/assessment/questions/weighted-multi-choice-answer.component.ts b/ui/src/app/review/assessment/questions/weighted-multi-choice-answer.component.ts index 8ac8fe5cf..6e7bb3aea 100644 --- a/ui/src/app/review/assessment/questions/weighted-multi-choice-answer.component.ts +++ b/ui/src/app/review/assessment/questions/weighted-multi-choice-answer.component.ts @@ -5,7 +5,8 @@ import { NgClass } from '@angular/common'; import { Component, Input } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; + import { MathJaxDirective } from 'src/app/shared/math/math-jax.directive'; import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe'; diff --git a/ui/src/app/review/assessment/sections/section.component.ts b/ui/src/app/review/assessment/sections/section.component.ts index 01fd81725..9ca7b9216 100644 --- a/ui/src/app/review/assessment/sections/section.component.ts +++ b/ui/src/app/review/assessment/sections/section.component.ts @@ -4,8 +4,10 @@ import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import type { Exam, ExamParticipation, ExamSection, ExamSectionQuestion } from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Exam, ExamSection } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; +import { ExamSectionQuestion } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { ClozeTestComponent } from 'src/app/review/assessment/questions/cloze-test.component'; import { EssayQuestionComponent } from 'src/app/review/assessment/questions/essay-question.component'; diff --git a/ui/src/app/review/listing/categories/archived.component.ts b/ui/src/app/review/listing/categories/archived.component.ts index d66ee8643..746cc1e9f 100644 --- a/ui/src/app/review/listing/categories/archived.component.ts +++ b/ui/src/app/review/listing/categories/archived.component.ts @@ -9,9 +9,8 @@ import { RouterLink } from '@angular/router'; import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import type { Exam } from 'src/app/exam/exam.model'; -import type { ReviewListView } from 'src/app/review/listing/review-list.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; -import type { Review } from 'src/app/review/review.model'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; diff --git a/ui/src/app/review/listing/categories/graded-logged.component.ts b/ui/src/app/review/listing/categories/graded-logged.component.ts index 7a7bbb83e..bc99f5688 100644 --- a/ui/src/app/review/listing/categories/graded-logged.component.ts +++ b/ui/src/app/review/listing/categories/graded-logged.component.ts @@ -20,9 +20,8 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { format } from 'date-fns'; import { ToastrService } from 'ngx-toastr'; import type { Exam } from 'src/app/exam/exam.model'; -import type { ReviewListView } from 'src/app/review/listing/review-list.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; -import type { Review } from 'src/app/review/review.model'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { FileService } from 'src/app/shared/file/file.service'; diff --git a/ui/src/app/review/listing/categories/graded.component.ts b/ui/src/app/review/listing/categories/graded.component.ts index 91ca7f721..d4545cd0f 100644 --- a/ui/src/app/review/listing/categories/graded.component.ts +++ b/ui/src/app/review/listing/categories/graded.component.ts @@ -21,9 +21,8 @@ import { ToastrService } from 'ngx-toastr'; import { forkJoin } from 'rxjs'; import type { Exam } from 'src/app/exam/exam.model'; import { AssessmentService } from 'src/app/review/assessment/assessment.service'; -import type { ReviewListView } from 'src/app/review/listing/review-list.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; -import type { Review } from 'src/app/review/review.model'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { DiffInDaysPipe } from 'src/app/shared/date/day-diff.pipe'; diff --git a/ui/src/app/review/listing/categories/in-language-inspection.component.ts b/ui/src/app/review/listing/categories/in-language-inspection.component.ts index a181213dc..e496b6fcc 100644 --- a/ui/src/app/review/listing/categories/in-language-inspection.component.ts +++ b/ui/src/app/review/listing/categories/in-language-inspection.component.ts @@ -9,9 +9,8 @@ import { RouterLink } from '@angular/router'; import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import type { Exam } from 'src/app/exam/exam.model'; -import type { ReviewListView } from 'src/app/review/listing/review-list.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; -import type { Review } from 'src/app/review/review.model'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { DiffInDaysPipe } from 'src/app/shared/date/day-diff.pipe'; diff --git a/ui/src/app/review/listing/categories/in-progress.component.ts b/ui/src/app/review/listing/categories/in-progress.component.ts index 5cfcace2b..0a4eebdfb 100644 --- a/ui/src/app/review/listing/categories/in-progress.component.ts +++ b/ui/src/app/review/listing/categories/in-progress.component.ts @@ -11,10 +11,9 @@ import { TranslateModule } from '@ngx-translate/core'; import { noop } from 'rxjs'; import type { Exam } from 'src/app/exam/exam.model'; import { ArchiveDownloadComponent } from 'src/app/review/listing/dialogs/archive-download.component'; -import type { ReviewListView } from 'src/app/review/listing/review-list.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; -import type { Review } from 'src/app/review/review.model'; -import type { User } from 'src/app/session/session.service'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { DiffInDaysPipe } from 'src/app/shared/date/day-diff.pipe'; diff --git a/ui/src/app/review/listing/categories/rejected.component.ts b/ui/src/app/review/listing/categories/rejected.component.ts index 20c7ee385..d5b919ec6 100644 --- a/ui/src/app/review/listing/categories/rejected.component.ts +++ b/ui/src/app/review/listing/categories/rejected.component.ts @@ -9,9 +9,8 @@ import { RouterLink } from '@angular/router'; import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import type { Exam } from 'src/app/exam/exam.model'; -import type { ReviewListView } from 'src/app/review/listing/review-list.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; -import type { Review } from 'src/app/review/review.model'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; import { SessionService } from 'src/app/session/session.service'; import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe'; import { DiffInDaysPipe } from 'src/app/shared/date/day-diff.pipe'; diff --git a/ui/src/app/review/listing/review-list.component.ts b/ui/src/app/review/listing/review-list.component.ts index d9ce32ec6..e2a6c78f8 100644 --- a/ui/src/app/review/listing/review-list.component.ts +++ b/ui/src/app/review/listing/review-list.component.ts @@ -8,9 +8,9 @@ import { Component, OnChanges, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { NgbModal, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { ExamTabService } from 'src/app/exam/editor/exam-tabs.service'; -import type { Exam, ExamParticipation } from 'src/app/exam/exam.model'; +import type { Exam } from 'src/app/exam/exam.model'; import type { Review } from 'src/app/review/review.model'; import { ArchivedReviewsComponent } from './categories/archived.component'; import { GradedLoggedReviewsComponent } from './categories/graded-logged.component'; diff --git a/ui/src/app/review/listing/review-list.service.ts b/ui/src/app/review/listing/review-list.service.ts index d8e37d73c..71be6ad43 100644 --- a/ui/src/app/review/listing/review-list.service.ts +++ b/ui/src/app/review/listing/review-list.service.ts @@ -9,22 +9,11 @@ import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { of } from 'rxjs'; import { map } from 'rxjs/operators'; -import type { ExamParticipation } from 'src/app/exam/exam.model'; -import type { Review } from 'src/app/review/review.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Review, ReviewListView } from 'src/app/review/review.model'; type Selection = { [k: string]: boolean }; -export type ReviewListView = { - items: Review[]; - filtered: Review[]; - toggle: boolean; - pageSize: number; - predicate: string; - reverse: boolean; - page: number; - filter: string; -}; - @Injectable({ providedIn: 'root' }) export class ReviewListService { constructor( diff --git a/ui/src/app/review/listing/speed-review.component.ts b/ui/src/app/review/listing/speed-review.component.ts index 8506de934..24069b5c7 100644 --- a/ui/src/app/review/listing/speed-review.component.ts +++ b/ui/src/app/review/listing/speed-review.component.ts @@ -14,19 +14,12 @@ import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; import { forkJoin, noop, throwError } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; -import type { - Course, - Exam, - ExamParticipation, - Grade, - GradeScale, - NoGrade, - SelectableGrade, -} from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import type { Course, Exam, Grade, GradeScale, NoGrade, SelectableGrade } from 'src/app/exam/exam.model'; import { isRealGrade } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; import type { Review } from 'src/app/review/review.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/review/listing/summary/exam-summary.component.ts b/ui/src/app/review/listing/summary/exam-summary.component.ts index 5bc69ea7c..b15a95efa 100644 --- a/ui/src/app/review/listing/summary/exam-summary.component.ts +++ b/ui/src/app/review/listing/summary/exam-summary.component.ts @@ -9,9 +9,9 @@ import { NgbModal, NgbPopover } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { Chart } from 'chart.js'; import { format } from 'date-fns'; -import type { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; +import type { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; import { ExamTabService } from 'src/app/exam/editor/exam-tabs.service'; -import type { Exam, ExamParticipation } from 'src/app/exam/exam.model'; +import type { Exam } from 'src/app/exam/exam.model'; import { AbortedExamsComponent } from 'src/app/review/listing/dialogs/aborted.component'; import { NoShowsComponent } from 'src/app/review/listing/dialogs/no-shows.component'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; diff --git a/ui/src/app/review/listing/summary/exam-summary.service.ts b/ui/src/app/review/listing/summary/exam-summary.service.ts index cae570bc5..041311fa2 100644 --- a/ui/src/app/review/listing/summary/exam-summary.service.ts +++ b/ui/src/app/review/listing/summary/exam-summary.service.ts @@ -23,9 +23,10 @@ import ChartDataLabels from 'chartjs-plugin-datalabels'; import { eachDayOfInterval, min, startOfDay } from 'date-fns'; import { countBy } from 'ramda'; import { of } from 'rxjs'; -import { ExamEnrolment } from 'src/app/enrolment/enrolment.model'; -import { Exam, ExamParticipation, Question } from 'src/app/exam/exam.model'; +import { ExamEnrolment, ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import { Exam } from 'src/app/exam/exam.model'; import { ExamService } from 'src/app/exam/exam.service'; +import { Question } from 'src/app/question/question.model'; import { QuestionService } from 'src/app/question/question.service'; import { ReviewListService } from 'src/app/review/listing/review-list.service'; import { CommonExamService } from 'src/app/shared/miscellaneous/common-exam.service'; diff --git a/ui/src/app/review/questions/assessment/question-assessment.component.ts b/ui/src/app/review/questions/assessment/question-assessment.component.ts index de6137fa0..bf15d0550 100644 --- a/ui/src/app/review/questions/assessment/question-assessment.component.ts +++ b/ui/src/app/review/questions/assessment/question-assessment.component.ts @@ -20,7 +20,7 @@ import { AssessmentService } from 'src/app/review/assessment/assessment.service' import { QuestionFlowComponent } from 'src/app/review/questions/flow/question-flow.component'; import { QuestionReviewService } from 'src/app/review/questions/question-review.service'; import type { QuestionReview, ReviewQuestion } from 'src/app/review/review.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { AttachmentService } from 'src/app/shared/attachment/attachment.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; diff --git a/ui/src/app/review/questions/question-review.service.ts b/ui/src/app/review/questions/question-review.service.ts index d28701f24..811314d8c 100644 --- a/ui/src/app/review/questions/question-review.service.ts +++ b/ui/src/app/review/questions/question-review.service.ts @@ -6,7 +6,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import type { Observable } from 'rxjs'; import type { QuestionReview, ReviewQuestion } from 'src/app/review/review.model'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { isNumber } from 'src/app/shared/miscellaneous/helpers'; @Injectable({ providedIn: 'root' }) diff --git a/ui/src/app/review/review.model.ts b/ui/src/app/review/review.model.ts index c49e97531..1fc05d44e 100644 --- a/ui/src/app/review/review.model.ts +++ b/ui/src/app/review/review.model.ts @@ -2,14 +2,10 @@ // // SPDX-License-Identifier: EUPL-1.2 -import type { - Attachment, - EssayAnswer, - ExamParticipation, - Question, - ReverseExamSectionQuestion, - SelectableGrade, -} from 'src/app/exam/exam.model'; +import { ExamParticipation } from 'src/app/enrolment/enrolment.model'; +import { SelectableGrade } from 'src/app/exam/exam.model'; +import { EssayAnswer, Question, ReverseExamSectionQuestion } from 'src/app/question/question.model'; +import { Attachment } from 'src/app/shared/attachment/attachment.model'; export interface ScorableEssayAnswer extends EssayAnswer { id: number; @@ -45,3 +41,21 @@ export type Review = { displayedGrade?: string; displayedCredit?: number; }; + +export interface Feedback { + comment: string; + id?: number; + attachment?: Attachment; + feedbackStatus?: boolean; +} + +export type ReviewListView = { + items: Review[]; + filtered: Review[]; + toggle: boolean; + pageSize: number; + predicate: string; + reverse: boolean; + page: number; + filter: string; +}; diff --git a/ui/src/app/session/dev/dev-login.component.ts b/ui/src/app/session/dev/dev-login.component.ts index efe9c075c..1df780ecc 100644 --- a/ui/src/app/session/dev/dev-login.component.ts +++ b/ui/src/app/session/dev/dev-login.component.ts @@ -5,7 +5,7 @@ import { Component, output } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; import { SessionService } from 'src/app/session/session.service'; import { PageContentComponent } from 'src/app/shared/components/page-content.component'; import { PageHeaderComponent } from 'src/app/shared/components/page-header.component'; diff --git a/ui/src/app/session/role/role-picker-dialog.component.ts b/ui/src/app/session/role/role-picker-dialog.component.ts index 95f5f98b4..65d3121be 100644 --- a/ui/src/app/session/role/role-picker-dialog.component.ts +++ b/ui/src/app/session/role/role-picker-dialog.component.ts @@ -6,7 +6,7 @@ import { NgClass } from '@angular/common'; import { Component, Input } from '@angular/core'; import { NgbActiveModal, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; -import type { User } from 'src/app/session/session.service'; +import type { User } from 'src/app/session/session.model'; @Component({ standalone: true, diff --git a/ui/src/app/session/session.model.ts b/ui/src/app/session/session.model.ts new file mode 100644 index 000000000..a9425e12a --- /dev/null +++ b/ui/src/app/session/session.model.ts @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +export interface Role { + name: string; + displayName?: string; + icon?: string; +} + +export enum PermissionType { + CAN_INSPECT_LANGUAGE = 'CAN_INSPECT_LANGUAGE', + CAN_CREATE_BYOD_EXAM = 'CAN_CREATE_BYOD_EXAM', +} + +export interface Permission { + id: number; + type: PermissionType; +} + +export interface User { + id: number; + eppn: string; + firstName: string; + lastName: string; + email: string; + lang: string; + loginRole: string | null; + roles: Role[]; + userAgreementAccepted: boolean; + userIdentifier: string; + permissions: { type: string }[]; + isAdmin: boolean; + isStudent: boolean; + isTeacher: boolean; + isLanguageInspector: boolean; + employeeNumber: string | null; + lastLogin: string | null; + canCreateByodExam: boolean; +} diff --git a/ui/src/app/session/session.service.ts b/ui/src/app/session/session.service.ts index 81a39c850..c9b364b6b 100644 --- a/ui/src/app/session/session.service.ts +++ b/ui/src/app/session/session.service.ts @@ -17,33 +17,7 @@ import { catchError, map, switchMap, tap } from 'rxjs/operators'; import { EulaDialogComponent } from './eula/eula-dialog.component'; import { SelectRoleDialogComponent } from './role/role-picker-dialog.component'; import { SessionExpireWarningComponent } from './session-timeout-toastr'; - -export interface Role { - name: string; - displayName?: string; - icon?: string; -} - -export interface User { - id: number; - eppn: string; - firstName: string; - lastName: string; - email: string; - lang: string; - loginRole: string | null; - roles: Role[]; - userAgreementAccepted: boolean; - userIdentifier: string; - permissions: { type: string }[]; - isAdmin: boolean; - isStudent: boolean; - isTeacher: boolean; - isLanguageInspector: boolean; - employeeNumber: string | null; - lastLogin: string | null; - canCreateByodExam: boolean; -} +import { Role, User } from './session.model'; interface Env { isProd: boolean; diff --git a/ui/src/app/shared/attachment/attachment.model.ts b/ui/src/app/shared/attachment/attachment.model.ts new file mode 100644 index 000000000..0096fbd87 --- /dev/null +++ b/ui/src/app/shared/attachment/attachment.model.ts @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2024 The members of the EXAM Consortium +// +// SPDX-License-Identifier: EUPL-1.2 + +export interface Attachment { + id?: number; + externalId?: string; + fileName: string; + removed: boolean; + modified: boolean; + size: number; + file?: File; + rev?: string; + objectVersion?: number; +} + +export interface FileResult { + $value: { attachmentFile: File }; +} + +export interface AnsweredQuestion { + id: number; + essayAnswer: { objectVersion: number; attachment?: { fileName: string } }; +} diff --git a/ui/src/app/shared/attachment/attachment.service.ts b/ui/src/app/shared/attachment/attachment.service.ts index 218651699..b674c71d5 100644 --- a/ui/src/app/shared/attachment/attachment.service.ts +++ b/ui/src/app/shared/attachment/attachment.service.ts @@ -8,19 +8,16 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; import { ToastrService } from 'ngx-toastr'; import type { Observable } from 'rxjs'; -import type { ReviewedExam } from 'src/app/enrolment/enrolment.model'; -import type { Exam, ExamParticipation, ExamSectionQuestion, Question } from 'src/app/exam/exam.model'; +import type { ExamParticipation, ReviewedExam } from 'src/app/enrolment/enrolment.model'; +import type { Exam } from 'src/app/exam/exam.model'; import type { Examination } from 'src/app/examination/examination.model'; +import { ExamSectionQuestion, Question } from 'src/app/question/question.model'; import type { ReviewQuestion } from 'src/app/review/review.model'; import { ConfirmationDialogService } from 'src/app/shared/dialogs/confirmation-dialog.service'; import { FileService } from 'src/app/shared/file/file.service'; -import type { FileResult } from './dialogs/attachment-picker.component'; +import { AnsweredQuestion, FileResult } from './attachment.model'; import { AttachmentSelectorComponent } from './dialogs/attachment-picker.component'; -export interface AnsweredQuestion { - id: number; - essayAnswer: { objectVersion: number; attachment?: { fileName: string } }; -} @Injectable({ providedIn: 'root' }) export class AttachmentService { constructor( diff --git a/ui/src/app/shared/attachment/dialogs/attachment-picker.component.ts b/ui/src/app/shared/attachment/dialogs/attachment-picker.component.ts index 4a449c325..f314b50fa 100644 --- a/ui/src/app/shared/attachment/dialogs/attachment-picker.component.ts +++ b/ui/src/app/shared/attachment/dialogs/attachment-picker.component.ts @@ -8,10 +8,6 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { FileService } from 'src/app/shared/file/file.service'; -export interface FileResult { - $value: { attachmentFile: File }; -} - /* file-select has been made accessible so that there is button (