diff --git a/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise.component.ts b/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise.component.ts index 01fe874b2afd..0874dea0faf6 100644 --- a/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise.component.ts +++ b/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise.component.ts @@ -1,28 +1,30 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; -import { ActivatedRoute, Router } from '@angular/router'; -import { TranslateService } from '@ngx-translate/core'; import { filter } from 'rxjs/operators'; import { FileUploadExercise } from 'app/entities/file-upload-exercise.model'; import { FileUploadExerciseService } from './file-upload-exercise.service'; import { ExerciseComponent } from 'app/exercises/shared/exercise/exercise.component'; import { onError } from 'app/shared/util/global.utils'; import { AccountService } from 'app/core/auth/account.service'; -import { CourseManagementService } from 'app/course/manage/course-management.service'; import { SortService } from 'app/shared/service/sort.service'; import { ExerciseService } from 'app/exercises/shared/exercise/exercise.service'; import { AlertService } from 'app/core/util/alert.service'; -import { EventManager } from 'app/core/util/event-manager.service'; import { faBook, faPlus, faSort, faTable, faTrash, faUsers, faWrench } from '@fortawesome/free-solid-svg-icons'; import { faListAlt } from '@fortawesome/free-regular-svg-icons'; import { CourseExerciseService } from 'app/exercises/shared/course-exercises/course-exercise.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'jhi-file-upload-exercise', templateUrl: './file-upload-exercise.component.html', }) export class FileUploadExerciseComponent extends ExerciseComponent { + protected exerciseService = inject(ExerciseService); + protected fileUploadExerciseService = inject(FileUploadExerciseService); + private courseExerciseService = inject(CourseExerciseService); + private alertService = inject(AlertService); + private accountService = inject(AccountService); + private sortService = inject(SortService); + @Input() fileUploadExercises: FileUploadExercise[] = []; filteredFileUploadExercises: FileUploadExercise[] = []; @@ -40,23 +42,6 @@ export class FileUploadExerciseComponent extends ExerciseComponent { return this.fileUploadExercises; } - constructor( - public exerciseService: ExerciseService, - public fileUploadExerciseService: FileUploadExerciseService, - private courseExerciseService: CourseExerciseService, - private alertService: AlertService, - private accountService: AccountService, - private modalService: NgbModal, - private router: Router, - private sortService: SortService, - courseService: CourseManagementService, - translateService: TranslateService, - eventManager: EventManager, - route: ActivatedRoute, - ) { - super(courseService, translateService, route, eventManager); - } - protected loadExercises(): void { this.courseExerciseService .findAllFileUploadExercisesForCourse(this.courseId) diff --git a/src/main/webapp/app/exercises/modeling/manage/modeling-exercise.component.ts b/src/main/webapp/app/exercises/modeling/manage/modeling-exercise.component.ts index 74dff3c4b9fc..e1ea83ce136e 100644 --- a/src/main/webapp/app/exercises/modeling/manage/modeling-exercise.component.ts +++ b/src/main/webapp/app/exercises/modeling/manage/modeling-exercise.component.ts @@ -1,18 +1,13 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { ModelingExercise } from 'app/entities/modeling-exercise.model'; import { ModelingExerciseService } from './modeling-exercise.service'; import { AccountService } from 'app/core/auth/account.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { ActivatedRoute, Router } from '@angular/router'; -import { CourseManagementService } from 'app/course/manage/course-management.service'; import { ExerciseComponent } from 'app/exercises/shared/exercise/exercise.component'; -import { TranslateService } from '@ngx-translate/core'; import { onError } from 'app/shared/util/global.utils'; import { SortService } from 'app/shared/service/sort.service'; import { ExerciseService } from 'app/exercises/shared/exercise/exercise.service'; import { AlertService } from 'app/core/util/alert.service'; -import { EventManager } from 'app/core/util/event-manager.service'; import { faBook, faPlus, faSort, faTable, faTimes, faTrash, faUsers, faWrench } from '@fortawesome/free-solid-svg-icons'; import { faListAlt } from '@fortawesome/free-regular-svg-icons'; import { CourseExerciseService } from 'app/exercises/shared/course-exercises/course-exercise.service'; @@ -22,7 +17,14 @@ import { CourseExerciseService } from 'app/exercises/shared/course-exercises/cou templateUrl: './modeling-exercise.component.html', }) export class ModelingExerciseComponent extends ExerciseComponent { - @Input() modelingExercises: ModelingExercise[]; + protected exerciseService = inject(ExerciseService); + protected modelingExerciseService = inject(ModelingExerciseService); + private courseExerciseService = inject(CourseExerciseService); + private alertService = inject(AlertService); + private accountService = inject(AccountService); + private sortService = inject(SortService); + + @Input() modelingExercises: ModelingExercise[] = []; filteredModelingExercises: ModelingExercise[]; // Icons faPlus = faPlus; @@ -39,24 +41,6 @@ export class ModelingExerciseComponent extends ExerciseComponent { return this.modelingExercises; } - constructor( - public exerciseService: ExerciseService, - public modelingExerciseService: ModelingExerciseService, - private courseExerciseService: CourseExerciseService, - private alertService: AlertService, - private accountService: AccountService, - private sortService: SortService, - private modalService: NgbModal, - private router: Router, - courseService: CourseManagementService, - translateService: TranslateService, - eventManager: EventManager, - route: ActivatedRoute, - ) { - super(courseService, translateService, route, eventManager); - this.modelingExercises = []; - } - protected loadExercises(): void { this.courseExerciseService.findAllModelingExercisesForCourse(this.courseId).subscribe({ next: (res: HttpResponse) => { diff --git a/src/main/webapp/app/exercises/programming/manage/programming-exercise.component.ts b/src/main/webapp/app/exercises/programming/manage/programming-exercise.component.ts index e1f659c87483..3a33c7b88f83 100644 --- a/src/main/webapp/app/exercises/programming/manage/programming-exercise.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/programming-exercise.component.ts @@ -1,23 +1,19 @@ -import { Component, ContentChild, Input, OnDestroy, OnInit, TemplateRef } from '@angular/core'; +import { Component, ContentChild, Input, OnDestroy, OnInit, TemplateRef, inject } from '@angular/core'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { merge } from 'rxjs'; import { ProgrammingExercise } from 'app/entities/programming/programming-exercise.model'; import { ProgrammingExerciseInstructorRepositoryType, ProgrammingExerciseService } from './services/programming-exercise.service'; -import { ActivatedRoute } from '@angular/router'; import { ExerciseComponent } from 'app/exercises/shared/exercise/exercise.component'; -import { TranslateService } from '@ngx-translate/core'; import { ActionType } from 'app/shared/delete-dialog/delete-dialog.model'; import { onError } from 'app/shared/util/global.utils'; import { AccountService } from 'app/core/auth/account.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { FeatureToggle } from 'app/shared/feature-toggle/feature-toggle.service'; import { ExerciseService } from 'app/exercises/shared/exercise/exercise.service'; -import { CourseManagementService } from 'app/course/manage/course-management.service'; import { SortService } from 'app/shared/service/sort.service'; import { ProgrammingExerciseEditSelectedComponent } from 'app/exercises/programming/manage/programming-exercise-edit-selected.component'; import { ProgrammingExerciseParticipationType } from 'app/entities/programming/programming-exercise-participation.model'; import { AlertService } from 'app/core/util/alert.service'; -import { EventManager } from 'app/core/util/event-manager.service'; import { createBuildPlanUrl } from 'app/exercises/programming/shared/utils/programming-exercise.utils'; import { ProfileService } from 'app/shared/layouts/profiles/profile.service'; import { ConsistencyCheckComponent } from 'app/shared/consistency-check/consistency-check.component'; @@ -46,7 +42,16 @@ import { PROFILE_LOCALCI, PROFILE_LOCALVC, PROFILE_THEIA } from 'app/app.constan templateUrl: './programming-exercise.component.html', }) export class ProgrammingExerciseComponent extends ExerciseComponent implements OnInit, OnDestroy { - @Input() programmingExercises: ProgrammingExercise[]; + protected exerciseService = inject(ExerciseService); + private programmingExerciseService = inject(ProgrammingExerciseService); + private courseExerciseService = inject(CourseExerciseService); + private accountService = inject(AccountService); + private alertService = inject(AlertService); + private modalService = inject(NgbModal); + private sortService = inject(SortService); + private profileService = inject(ProfileService); + + @Input() programmingExercises: ProgrammingExercise[] = []; filteredProgrammingExercises: ProgrammingExercise[]; readonly ActionType = ActionType; FeatureToggle = FeatureToggle; @@ -82,24 +87,6 @@ export class ProgrammingExerciseComponent extends ExerciseComponent implements O return this.programmingExercises; } - constructor( - private programmingExerciseService: ProgrammingExerciseService, - private courseExerciseService: CourseExerciseService, - public exerciseService: ExerciseService, - private accountService: AccountService, - private alertService: AlertService, - private modalService: NgbModal, - private sortService: SortService, - private profileService: ProfileService, - courseService: CourseManagementService, - translateService: TranslateService, - eventManager: EventManager, - route: ActivatedRoute, - ) { - super(courseService, translateService, route, eventManager); - this.programmingExercises = []; - } - ngOnInit(): void { super.ngOnInit(); } diff --git a/src/main/webapp/app/exercises/quiz/manage/quiz-exercise.component.ts b/src/main/webapp/app/exercises/quiz/manage/quiz-exercise.component.ts index 7e3f76e29b65..22ac2e1a7685 100644 --- a/src/main/webapp/app/exercises/quiz/manage/quiz-exercise.component.ts +++ b/src/main/webapp/app/exercises/quiz/manage/quiz-exercise.component.ts @@ -1,18 +1,13 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { QuizExercise, QuizMode, QuizStatus } from 'app/entities/quiz/quiz-exercise.model'; import { QuizExerciseService } from './quiz-exercise.service'; import { AccountService } from 'app/core/auth/account.service'; -import { ActivatedRoute, Router } from '@angular/router'; -import { CourseManagementService } from 'app/course/manage/course-management.service'; import { ExerciseComponent } from 'app/exercises/shared/exercise/exercise.component'; -import { TranslateService } from '@ngx-translate/core'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ActionType } from 'app/shared/delete-dialog/delete-dialog.model'; import { SortService } from 'app/shared/service/sort.service'; import { ExerciseService } from 'app/exercises/shared/exercise/exercise.service'; import { AlertService } from 'app/core/util/alert.service'; -import { EventManager } from 'app/core/util/event-manager.service'; import { faSort, faTrash } from '@fortawesome/free-solid-svg-icons'; import { isQuizEditable } from 'app/exercises/quiz/shared/quiz-manage-util.service'; @@ -21,6 +16,12 @@ import { isQuizEditable } from 'app/exercises/quiz/shared/quiz-manage-util.servi templateUrl: './quiz-exercise.component.html', }) export class QuizExerciseComponent extends ExerciseComponent { + protected exerciseService = inject(ExerciseService); + quizExerciseService = inject(QuizExerciseService); + private accountService = inject(AccountService); + private alertService = inject(AlertService); + private sortService = inject(SortService); + readonly ActionType = ActionType; readonly QuizStatus = QuizStatus; readonly QuizMode = QuizMode; @@ -36,22 +37,6 @@ export class QuizExerciseComponent extends ExerciseComponent { return this.quizExercises; } - constructor( - public quizExerciseService: QuizExerciseService, - private accountService: AccountService, - private alertService: AlertService, - private modalService: NgbModal, - private router: Router, - private sortService: SortService, - public exerciseService: ExerciseService, - courseService: CourseManagementService, - translateService: TranslateService, - eventManager: EventManager, - route: ActivatedRoute, - ) { - super(courseService, translateService, route, eventManager); - } - protected loadExercises(): void { this.quizExerciseService.findForCourse(this.courseId).subscribe({ next: (res: HttpResponse) => { diff --git a/src/main/webapp/app/exercises/shared/exercise/exercise.component.ts b/src/main/webapp/app/exercises/shared/exercise/exercise.component.ts index fccf7cdb3269..32d96f26b6f7 100644 --- a/src/main/webapp/app/exercises/shared/exercise/exercise.component.ts +++ b/src/main/webapp/app/exercises/shared/exercise/exercise.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, Subject, Subscription, merge } from 'rxjs'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; @@ -15,6 +15,11 @@ interface DeletionServiceInterface { @Component({ template: '' }) export abstract class ExerciseComponent implements OnInit, OnDestroy { + protected translateService = inject(TranslateService); + protected eventManager = inject(EventManager); + private courseService = inject(CourseManagementService); + private route = inject(ActivatedRoute); + private eventSubscriber: Subscription; @Input() embedded = false; @Input() course: Course; @@ -23,8 +28,8 @@ export abstract class ExerciseComponent implements OnInit, OnDestroy { @Output() filteredExerciseCount = new EventEmitter(); showHeading: boolean; courseId: number; - predicate: string; - reverse: boolean; + predicate: string = 'id'; + reverse: boolean = true; selectedExercises: Exercise[] = []; allChecked = false; @@ -35,16 +40,6 @@ export abstract class ExerciseComponent implements OnInit, OnDestroy { protected abstract get exercises(): Exercise[]; - protected constructor( - private courseService: CourseManagementService, - protected translateService: TranslateService, - private route: ActivatedRoute, - protected eventManager: EventManager, - ) { - this.predicate = 'id'; - this.reverse = true; - } - /** * Fetches an exercise from the server (and if needed the course as well) */ diff --git a/src/main/webapp/app/exercises/text/assess/analytics/text-assesment-analytics.service.ts b/src/main/webapp/app/exercises/text/assess/analytics/text-assesment-analytics.service.ts index 22178ca78f3c..b48b4dbca3ff 100644 --- a/src/main/webapp/app/exercises/text/assess/analytics/text-assesment-analytics.service.ts +++ b/src/main/webapp/app/exercises/text/assess/analytics/text-assesment-analytics.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TextAssessmentService } from 'app/exercises/text/assess/text-assessment.service'; import { TextAssessmentEvent, TextAssessmentEventType } from 'app/entities/text/text-assesment-event.model'; @@ -13,6 +13,11 @@ import { Location } from '@angular/common'; */ @Injectable({ providedIn: 'root' }) export class TextAssessmentAnalytics { + protected assessmentsService = inject(TextAssessmentService); + protected accountService = inject(AccountService); + private location = inject(Location); + private profileService = inject(ProfileService); + private userId: number; private courseId: number; private textExerciseId: number; @@ -23,12 +28,7 @@ export class TextAssessmentAnalytics { private route: ActivatedRoute; public analyticsEnabled = false; - constructor( - protected assessmentsService: TextAssessmentService, - protected accountService: AccountService, - private profileService: ProfileService, - public location: Location, - ) { + constructor() { // retrieve the analytics enabled status from the profile info and set to current property this.profileService.getProfileInfo().subscribe((profileInfo) => { this.analyticsEnabled = profileInfo.textAssessmentAnalyticsEnabled || false; diff --git a/src/main/webapp/app/exercises/text/assess/text-assessment-area/text-assessment-area.component.ts b/src/main/webapp/app/exercises/text/assess/text-assessment-area/text-assessment-area.component.ts index 200f7b69d95a..2646fccb48ad 100644 --- a/src/main/webapp/app/exercises/text/assess/text-assessment-area/text-assessment-area.component.ts +++ b/src/main/webapp/app/exercises/text/assess/text-assessment-area/text-assessment-area.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges, inject } from '@angular/core'; import { TextSubmission } from 'app/entities/text/text-submission.model'; import { TextBlockRef } from 'app/entities/text/text-block-ref.model'; import { StringCountService } from 'app/exercises/text/participate/string-count.service'; @@ -16,6 +16,8 @@ import { GradingCriterion } from 'app/exercises/shared/structured-grading-criter ], }) export class TextAssessmentAreaComponent implements OnChanges { + private stringCountService = inject(StringCountService); + // inputs @Input() submission: TextSubmission; @Input() textBlockRefs: TextBlockRef[]; @@ -32,8 +34,6 @@ export class TextAssessmentAreaComponent implements OnChanges { wordCount = 0; characterCount = 0; - constructor(private stringCountService: StringCountService) {} - /** * Life cycle hook to indicate component change */ diff --git a/src/main/webapp/app/exercises/text/assess/text-assessment-base.component.ts b/src/main/webapp/app/exercises/text/assess/text-assessment-base.component.ts index 8c1f564182d5..a3c60d5352ee 100644 --- a/src/main/webapp/app/exercises/text/assess/text-assessment-base.component.ts +++ b/src/main/webapp/app/exercises/text/assess/text-assessment-base.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { TextBlockRef } from 'app/entities/text/text-block-ref.model'; import { TextSubmission } from 'app/entities/text/text-submission.model'; @@ -17,6 +17,11 @@ import { getCourseFromExercise } from 'app/entities/exercise.model'; template: '', }) export abstract class TextAssessmentBaseComponent implements OnInit { + protected alertService = inject(AlertService); + protected accountService = inject(AccountService); + protected assessmentsService = inject(TextAssessmentService); + protected structuredGradingCriterionService = inject(StructuredGradingCriterionService); + /* * Base Component for TextSubmissionAssessmentComponent and ExampleTextSubmissionComponent since they share a lot of same functions. */ @@ -29,13 +34,6 @@ export abstract class TextAssessmentBaseComponent implements OnInit { readonly getCourseFromExercise = getCourseFromExercise; - protected constructor( - protected alertService: AlertService, - protected accountService: AccountService, - protected assessmentsService: TextAssessmentService, - protected structuredGradingCriterionService: StructuredGradingCriterionService, - ) {} - async ngOnInit() { // Used to check if the assessor is the current user const identity = await this.accountService.identity(); diff --git a/src/main/webapp/app/exercises/text/assess/text-assessment.service.ts b/src/main/webapp/app/exercises/text/assess/text-assessment.service.ts index 492d620afe9c..6304b95f1625 100644 --- a/src/main/webapp/app/exercises/text/assess/text-assessment.service.ts +++ b/src/main/webapp/app/exercises/text/assess/text-assessment.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; @@ -22,12 +22,10 @@ type TextAssessmentDTO = { feedbacks: Feedback[]; textBlocks: TextBlock[]; asses providedIn: 'root', }) export class TextAssessmentService { - private readonly RESOURCE_URL = 'api'; + private http = inject(HttpClient); + private accountService = inject(AccountService); - constructor( - private http: HttpClient, - private accountService: AccountService, - ) {} + private readonly RESOURCE_URL = 'api'; /** * Saves the passed feedback items of the assessment. diff --git a/src/main/webapp/app/exercises/text/assess/text-submission-assessment.component.ts b/src/main/webapp/app/exercises/text/assess/text-submission-assessment.component.ts index ed71e52c21d4..1d710d15ac1f 100644 --- a/src/main/webapp/app/exercises/text/assess/text-submission-assessment.component.ts +++ b/src/main/webapp/app/exercises/text/assess/text-submission-assessment.component.ts @@ -1,10 +1,8 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject } from '@angular/core'; import { Location } from '@angular/common'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; -import { AlertService } from 'app/core/util/alert.service'; import dayjs from 'dayjs/esm'; -import { AccountService } from 'app/core/auth/account.service'; import { StudentParticipation } from 'app/entities/participation/student-participation.model'; import { TextSubmission } from 'app/entities/text/text-submission.model'; import { TextExercise } from 'app/entities/text/text-exercise.model'; @@ -16,7 +14,6 @@ import { Feedback, FeedbackType } from 'app/entities/feedback.model'; import { notUndefined, onError } from 'app/shared/util/global.utils'; import { TranslateService } from '@ngx-translate/core'; import { NEW_ASSESSMENT_PATH } from 'app/exercises/text/assess/text-submission-assessment.route'; -import { StructuredGradingCriterionService } from 'app/exercises/shared/structured-grading-criterion/structured-grading-criterion.service'; import { assessmentNavigateBack } from 'app/exercises/shared/navigate-back.util'; import { getLatestSubmissionResult, @@ -45,6 +42,16 @@ import { Subscription } from 'rxjs'; styleUrls: ['./text-submission-assessment.component.scss'], }) export class TextSubmissionAssessmentComponent extends TextAssessmentBaseComponent implements OnInit, OnDestroy { + private activatedRoute = inject(ActivatedRoute); + private router = inject(Router); + private location = inject(Location); + private route = inject(ActivatedRoute); + private complaintService = inject(ComplaintService); + private submissionService = inject(SubmissionService); + private exampleSubmissionService = inject(ExampleSubmissionService); + private athenaService = inject(AthenaService); + private translateService = inject(TranslateService); + /* * The instance of this component is REUSED for multiple assessments if using the "Assess Next" button! * All properties must be initialized with a default value (or null) in the resetComponent() method. @@ -66,7 +73,7 @@ export class TextSubmissionAssessmentComponent extends TextAssessmentBaseCompone assessmentsAreValid: boolean; noNewSubmissions: boolean; hasAssessmentDueDatePassed: boolean; - correctionRound: number; + correctionRound: number = 0; resultId: number; loadingInitialSubmission = true; highlightDifferences = false; @@ -99,24 +106,9 @@ export class TextSubmissionAssessmentComponent extends TextAssessmentBaseCompone // Icons farListAlt = faListAlt; - constructor( - private activatedRoute: ActivatedRoute, - private router: Router, - private location: Location, - private route: ActivatedRoute, - private complaintService: ComplaintService, - private submissionService: SubmissionService, - private exampleSubmissionService: ExampleSubmissionService, - private athenaService: AthenaService, - alertService: AlertService, - accountService: AccountService, - assessmentsService: TextAssessmentService, - structuredGradingCriterionService: StructuredGradingCriterionService, - translateService: TranslateService, - ) { - super(alertService, accountService, assessmentsService, structuredGradingCriterionService); - translateService.get('artemisApp.textAssessment.confirmCancel').subscribe((text) => (this.cancelConfirmationText = text)); - this.correctionRound = 0; + constructor() { + super(); + this.translateService.get('artemisApp.textAssessment.confirmCancel').subscribe((text) => (this.cancelConfirmationText = text)); this.resetComponent(); } diff --git a/src/main/webapp/app/exercises/text/assess/text-submission-assessment.route.ts b/src/main/webapp/app/exercises/text/assess/text-submission-assessment.route.ts index 83e63bcd21b1..aa8fb3f15542 100644 --- a/src/main/webapp/app/exercises/text/assess/text-submission-assessment.route.ts +++ b/src/main/webapp/app/exercises/text/assess/text-submission-assessment.route.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { ActivatedRouteSnapshot, Resolve, Routes } from '@angular/router'; import { TextSubmission } from 'app/entities/text/text-submission.model'; import { of } from 'rxjs'; @@ -12,7 +12,7 @@ import { catchError, map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class NewStudentParticipationResolver implements Resolve { - constructor(private textSubmissionService: TextSubmissionService) {} + private textSubmissionService = inject(TextSubmissionService); /** * Resolves the needed StudentParticipations for the TextSubmissionAssessmentComponent using the TextAssessmentService. @@ -33,7 +33,7 @@ export class NewStudentParticipationResolver implements Resolve { - constructor(private textAssessmentService: TextAssessmentService) {} + private textAssessmentService = inject(TextAssessmentService); /** * Resolves the needed StudentParticipations for the TextSubmissionAssessmentComponent using the TextAssessmentService. diff --git a/src/main/webapp/app/exercises/text/assess/textblock-assessment-card/textblock-assessment-card.component.ts b/src/main/webapp/app/exercises/text/assess/textblock-assessment-card/textblock-assessment-card.component.ts index 2a34e2b47136..402d82924caa 100644 --- a/src/main/webapp/app/exercises/text/assess/textblock-assessment-card/textblock-assessment-card.component.ts +++ b/src/main/webapp/app/exercises/text/assess/textblock-assessment-card/textblock-assessment-card.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ViewChild, inject } from '@angular/core'; import { TextBlockRef } from 'app/entities/text/text-block-ref.model'; import { TextblockFeedbackEditorComponent } from 'app/exercises/text/assess/textblock-feedback-editor/textblock-feedback-editor.component'; import { StructuredGradingCriterionService } from 'app/exercises/shared/structured-grading-criterion/structured-grading-criterion.service'; @@ -17,6 +17,10 @@ type OptionalTextBlockRef = TextBlockRef | undefined; styleUrls: ['./textblock-assessment-card.component.scss'], }) export class TextblockAssessmentCardComponent { + protected route = inject(ActivatedRoute); + private structuredGradingCriterionService = inject(StructuredGradingCriterionService); + textAssessmentAnalytics = inject(TextAssessmentAnalytics); + @Input() textBlockRef: TextBlockRef; @Input() selected = false; @Input() readOnly: boolean; @@ -29,12 +33,8 @@ export class TextblockAssessmentCardComponent { @Output() didDelete = new EventEmitter(); @ViewChild(TextblockFeedbackEditorComponent) feedbackEditor: TextblockFeedbackEditorComponent; - constructor( - public structuredGradingCriterionService: StructuredGradingCriterionService, - public textAssessmentAnalytics: TextAssessmentAnalytics, - protected route: ActivatedRoute, - ) { - textAssessmentAnalytics.setComponentRoute(route); + constructor() { + this.textAssessmentAnalytics.setComponentRoute(this.route); } /** diff --git a/src/main/webapp/app/exercises/text/assess/textblock-feedback-editor/textblock-feedback-editor.component.ts b/src/main/webapp/app/exercises/text/assess/textblock-feedback-editor/textblock-feedback-editor.component.ts index 0cae1c87a35b..d52448b4164c 100644 --- a/src/main/webapp/app/exercises/text/assess/textblock-feedback-editor/textblock-feedback-editor.component.ts +++ b/src/main/webapp/app/exercises/text/assess/textblock-feedback-editor/textblock-feedback-editor.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, EventEmitter, HostBinding, Input, Output, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, EventEmitter, HostBinding, Input, Output, ViewChild, inject } from '@angular/core'; import { TextBlock } from 'app/entities/text/text-block.model'; import { Feedback, FeedbackType } from 'app/entities/feedback.model'; import { ConfirmIconComponent } from 'app/shared/confirm-icon/confirm-icon.component'; @@ -16,6 +16,11 @@ import { GradingCriterion } from 'app/exercises/shared/structured-grading-criter styleUrls: ['./textblock-feedback-editor.component.scss'], }) export class TextblockFeedbackEditorComponent implements AfterViewInit { + protected route = inject(ActivatedRoute); + protected modalService = inject(NgbModal); + structuredGradingCriterionService = inject(StructuredGradingCriterionService); + textAssessmentAnalytics = inject(TextAssessmentAnalytics); + readonly FeedbackType = FeedbackType; @Input() textBlock: TextBlock = new TextBlock(); @@ -55,13 +60,8 @@ export class TextblockFeedbackEditorComponent implements AfterViewInit { faTrash = faTrash; faAngleRight = faAngleRight; - constructor( - public structuredGradingCriterionService: StructuredGradingCriterionService, - protected modalService: NgbModal, - protected route: ActivatedRoute, - public textAssessmentAnalytics: TextAssessmentAnalytics, - ) { - textAssessmentAnalytics.setComponentRoute(route); + constructor() { + this.textAssessmentAnalytics.setComponentRoute(this.route); } /** diff --git a/src/main/webapp/app/exercises/text/manage/example-text-submission/example-text-submission.component.ts b/src/main/webapp/app/exercises/text/manage/example-text-submission/example-text-submission.component.ts index 1640da7b1978..9592fcd4c481 100644 --- a/src/main/webapp/app/exercises/text/manage/example-text-submission/example-text-submission.component.ts +++ b/src/main/webapp/app/exercises/text/manage/example-text-submission/example-text-submission.component.ts @@ -1,11 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { AlertService } from 'app/core/util/alert.service'; import { HttpResponse } from '@angular/common/http'; import { EntityResponseType, ExampleSubmissionService } from 'app/exercises/shared/example-submission/example-submission.service'; import { TextAssessmentService } from 'app/exercises/text/assess/text-assessment.service'; import { TutorParticipationService } from 'app/exercises/shared/dashboards/tutor/tutor-participation.service'; -import { AccountService } from 'app/core/auth/account.service'; import { GuidedTourService } from 'app/guided-tour/guided-tour.service'; import { tutorAssessmentTour } from 'app/guided-tour/tours/tutor-assessment-tour'; import { ExampleSubmission, ExampleSubmissionMode } from 'app/entities/example-submission.model'; @@ -16,7 +14,6 @@ import { TextSubmission } from 'app/entities/text/text-submission.model'; import { Result } from 'app/entities/result.model'; import { setLatestSubmissionResult } from 'app/entities/submission.model'; import { TextAssessmentBaseComponent } from 'app/exercises/text/assess/text-assessment-base.component'; -import { StructuredGradingCriterionService } from 'app/exercises/shared/structured-grading-criterion/structured-grading-criterion.service'; import { notUndefined } from 'app/shared/util/global.utils'; import { AssessButtonStates, Context, State, SubmissionButtonStates, UIStates } from 'app/exercises/text/manage/example-text-submission/example-text-submission-state.model'; import { filter, mergeMap, switchMap, tap } from 'rxjs/operators'; @@ -35,6 +32,14 @@ type ExampleSubmissionResponseType = EntityResponseType; styleUrls: ['./example-text-submission.component.scss'], }) export class ExampleTextSubmissionComponent extends TextAssessmentBaseComponent implements OnInit, Context, FeedbackMarker { + private route = inject(ActivatedRoute); + private router = inject(Router); + private exampleSubmissionService = inject(ExampleSubmissionService); + private tutorParticipationService = inject(TutorParticipationService); + private guidedTourService = inject(GuidedTourService); + private navigationUtilService = inject(ArtemisNavigationUtilService); + private exerciseService = inject(ExerciseService); + isNewSubmission: boolean; areNewAssessments = true; @@ -62,20 +67,8 @@ export class ExampleTextSubmissionComponent extends TextAssessmentBaseComponent faEdit = faEdit; farListAlt = faListAlt; - constructor( - private exampleSubmissionService: ExampleSubmissionService, - private tutorParticipationService: TutorParticipationService, - private route: ActivatedRoute, - private router: Router, - private guidedTourService: GuidedTourService, - private navigationUtilService: ArtemisNavigationUtilService, - private exerciseService: ExerciseService, - alertService: AlertService, - accountService: AccountService, - assessmentsService: TextAssessmentService, - structuredGradingCriterionService: StructuredGradingCriterionService, - ) { - super(alertService, accountService, assessmentsService, structuredGradingCriterionService); + constructor() { + super(); this.textBlockRefs = []; this.unusedTextBlockRefs = []; this.submission = new TextSubmission(); diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-detail.component.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-detail.component.ts index e758013e44ee..92c75b1db510 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-detail.component.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-detail.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject } from '@angular/core'; import { SafeHtml } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; import { HttpResponse } from '@angular/common/http'; @@ -29,6 +29,12 @@ import { templateUrl: './text-exercise-detail.component.html', }) export class TextExerciseDetailComponent implements OnInit, OnDestroy { + private route = inject(ActivatedRoute); + private eventManager = inject(EventManager); + private artemisMarkdownService = inject(ArtemisMarkdownService); + private textExerciseService = inject(TextExerciseService); + private statisticsService = inject(StatisticsService); + readonly documentationType: DocumentationType = 'Text'; readonly AssessmentType = AssessmentType; @@ -48,14 +54,6 @@ export class TextExerciseDetailComponent implements OnInit, OnDestroy { private subscription: Subscription; private eventSubscriber: Subscription; - constructor( - private eventManager: EventManager, - private textExerciseService: TextExerciseService, - private route: ActivatedRoute, - private artemisMarkdown: ArtemisMarkdownService, - private statisticsService: StatisticsService, - ) {} - /** * Loads the text exercise and subscribes to changes of it on component initialization. */ @@ -78,9 +76,9 @@ export class TextExerciseDetailComponent implements OnInit, OnDestroy { this.isExamExercise = !!this.textExercise.exerciseGroup; this.course = this.isExamExercise ? this.textExercise.exerciseGroup?.exam?.course : this.textExercise.course; - this.formattedGradingInstructions = this.artemisMarkdown.safeHtmlForMarkdown(this.textExercise.gradingInstructions); - this.formattedProblemStatement = this.artemisMarkdown.safeHtmlForMarkdown(this.textExercise.problemStatement); - this.formattedExampleSolution = this.artemisMarkdown.safeHtmlForMarkdown(this.textExercise.exampleSolution); + this.formattedGradingInstructions = this.artemisMarkdownService.safeHtmlForMarkdown(this.textExercise.gradingInstructions); + this.formattedProblemStatement = this.artemisMarkdownService.safeHtmlForMarkdown(this.textExercise.problemStatement); + this.formattedExampleSolution = this.artemisMarkdownService.safeHtmlForMarkdown(this.textExercise.exampleSolution); this.detailOverviewSections = this.getExerciseDetailSections(); }); this.statisticsService.getExerciseStatistics(exerciseId).subscribe((statistics: ExerciseManagementStatisticsDto) => { diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-paging.service.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-paging.service.ts index ed167d578dd0..6f5538b09ed1 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-paging.service.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-paging.service.ts @@ -1,5 +1,5 @@ import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { TextExercise } from 'app/entities/text/text-exercise.model'; import { ExercisePagingService } from 'app/exercises/shared/manage/exercise-paging.service'; @@ -7,7 +7,8 @@ import { ExercisePagingService } from 'app/exercises/shared/manage/exercise-pagi export class TextExercisePagingService extends ExercisePagingService { private static readonly RESOURCE_URL = 'api/text-exercises'; - constructor(http: HttpClient) { + constructor() { + const http = inject(HttpClient); super(http, TextExercisePagingService.RESOURCE_URL); } } diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-row-buttons.component.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-row-buttons.component.ts index 00e2973a5cc6..a1aab34bf04f 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-row-buttons.component.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-row-buttons.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { HttpErrorResponse } from '@angular/common/http'; import { Subject } from 'rxjs'; import { TextExerciseService } from 'app/exercises/text/manage/text-exercise/text-exercise.service'; @@ -12,6 +12,9 @@ import { faListAlt } from '@fortawesome/free-regular-svg-icons'; templateUrl: './text-exercise-row-buttons.component.html', }) export class TextExerciseRowButtonsComponent { + private eventManager = inject(EventManager); + private textExerciseService = inject(TextExerciseService); + @Input() courseId: number; @Input() exercise: TextExercise; private dialogErrorSource = new Subject(); @@ -25,11 +28,6 @@ export class TextExerciseRowButtonsComponent { faTable = faTable; farListAlt = faListAlt; - constructor( - private textExerciseService: TextExerciseService, - private eventManager: EventManager, - ) {} - deleteExercise() { this.textExerciseService.delete(this.exercise.id!).subscribe({ next: () => { diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-update.component.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-update.component.ts index e6abb283f200..18a5e8131205 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-update.component.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise-update.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { HttpErrorResponse } from '@angular/common/http'; import { TextExercise } from 'app/entities/text/text-exercise.model'; @@ -37,6 +37,18 @@ import { FormulaAction } from 'app/shared/monaco-editor/model/actions/formula.ac changeDetection: ChangeDetectionStrategy.OnPush, }) export class TextExerciseUpdateComponent implements OnInit, OnDestroy, AfterViewInit { + private activatedRoute = inject(ActivatedRoute); + private alertService = inject(AlertService); + private textExerciseService = inject(TextExerciseService); + private modalService = inject(NgbModal); + private popupService = inject(ExerciseUpdateWarningService); + private exerciseService = inject(ExerciseService); + private exerciseGroupService = inject(ExerciseGroupService); + private courseService = inject(CourseManagementService); + private eventManager = inject(EventManager); + private navigationUtilService = inject(ArtemisNavigationUtilService); + private athenaService = inject(AthenaService); + readonly IncludedInOverallScore = IncludedInOverallScore; readonly documentationType: DocumentationType = 'Text'; @@ -78,20 +90,6 @@ export class TextExerciseUpdateComponent implements OnInit, OnDestroy, AfterView plagiarismSubscription?: Subscription; teamSubscription?: Subscription; - constructor( - private alertService: AlertService, - private textExerciseService: TextExerciseService, - private modalService: NgbModal, - private popupService: ExerciseUpdateWarningService, - private exerciseService: ExerciseService, - private exerciseGroupService: ExerciseGroupService, - private courseService: CourseManagementService, - private eventManager: EventManager, - private activatedRoute: ActivatedRoute, - private navigationUtilService: ArtemisNavigationUtilService, - private athenaService: AthenaService, - ) {} - get editType(): EditType { if (this.isImport) { return EditType.IMPORT; diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.component.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.component.ts index ac46f89650d7..1ab47a466b49 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.component.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.component.ts @@ -1,19 +1,16 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { ExerciseType } from 'app/entities/exercise.model'; import { TextExercise } from 'app/entities/text/text-exercise.model'; import { TextExerciseService } from './text-exercise.service'; -import { CourseManagementService } from 'app/course/manage/course-management.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { ExerciseComponent } from 'app/exercises/shared/exercise/exercise.component'; -import { TranslateService } from '@ngx-translate/core'; import { onError } from 'app/shared/util/global.utils'; import { AccountService } from 'app/core/auth/account.service'; import { SortService } from 'app/shared/service/sort.service'; import { ExerciseService } from 'app/exercises/shared/exercise/exercise.service'; import { AlertService } from 'app/core/util/alert.service'; -import { EventManager } from 'app/core/util/event-manager.service'; import { faPlus, faSort, faTrash } from '@fortawesome/free-solid-svg-icons'; import { CourseExerciseService } from 'app/exercises/shared/course-exercises/course-exercise.service'; import { ExerciseImportWrapperComponent } from 'app/exercises/shared/import/exercise-import-wrapper/exercise-import-wrapper.component'; @@ -23,8 +20,17 @@ import { ExerciseImportWrapperComponent } from 'app/exercises/shared/import/exer templateUrl: './text-exercise.component.html', }) export class TextExerciseComponent extends ExerciseComponent { - @Input() textExercises: TextExercise[]; - filteredTextExercises: TextExercise[]; + protected exerciseService = inject(ExerciseService); + protected textExerciseService = inject(TextExerciseService); + private router = inject(Router); + private courseExerciseService = inject(CourseExerciseService); + private modalService = inject(NgbModal); + private alertService = inject(AlertService); + private sortService = inject(SortService); + private accountService = inject(AccountService); + + @Input() textExercises: TextExercise[] = []; + filteredTextExercises: TextExercise[] = []; // Icons faSort = faSort; @@ -35,25 +41,6 @@ export class TextExerciseComponent extends ExerciseComponent { return this.textExercises; } - constructor( - public exerciseService: ExerciseService, - public textExerciseService: TextExerciseService, - private courseExerciseService: CourseExerciseService, - private modalService: NgbModal, - private router: Router, - courseService: CourseManagementService, - translateService: TranslateService, - private alertService: AlertService, - private sortService: SortService, - eventManager: EventManager, - route: ActivatedRoute, - private accountService: AccountService, - ) { - super(courseService, translateService, route, eventManager); - this.textExercises = []; - this.filteredTextExercises = []; - } - protected loadExercises(): void { this.courseExerciseService.findAllTextExercisesForCourse(this.courseId).subscribe({ next: (res: HttpResponse) => { diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.route.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.route.ts index 30d4763745fc..d5431d66cc5f 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.route.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.route.ts @@ -3,7 +3,7 @@ import { UserRouteAccessService } from 'app/core/auth/user-route-access-service' import { TextExerciseDetailComponent } from './text-exercise-detail.component'; import { TextExerciseUpdateComponent } from './text-exercise-update.component'; import { TextExercise } from 'app/entities/text/text-exercise.model'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { TextExerciseService } from 'app/exercises/text/manage/text-exercise/text-exercise.service'; import { CourseManagementService } from 'app/course/manage/course-management.service'; import { of } from 'rxjs'; @@ -19,11 +19,9 @@ import { ExampleSubmissionsComponent } from 'app/exercises/shared/example-submis @Injectable({ providedIn: 'root' }) export class TextExerciseResolver implements Resolve { - constructor( - private textExerciseService: TextExerciseService, - private courseService: CourseManagementService, - private exerciseGroupService: ExerciseGroupService, - ) {} + private textExerciseService = inject(TextExerciseService); + private courseService = inject(CourseManagementService); + private exerciseGroupService = inject(ExerciseGroupService); /** * Resolves the route and initializes text exercise diff --git a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.service.ts b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.service.ts index 994f1ac75eeb..5c6b9275b3a1 100644 --- a/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.service.ts +++ b/src/main/webapp/app/exercises/text/manage/text-exercise/text-exercise.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -16,12 +16,10 @@ export type EntityArrayResponseType = HttpResponse; @Injectable({ providedIn: 'root' }) export class TextExerciseService implements ExerciseServicable { - private resourceUrl = 'api/text-exercises'; + private http = inject(HttpClient); + private exerciseService = inject(ExerciseService); - constructor( - private http: HttpClient, - private exerciseService: ExerciseService, - ) {} + private resourceUrl = 'api/text-exercises'; /** * Store a new text exercise on the server. diff --git a/src/main/webapp/app/exercises/text/manage/tutor-effort/tutor-effort-statistics.component.ts b/src/main/webapp/app/exercises/text/manage/tutor-effort/tutor-effort-statistics.component.ts index e6c54d0ce175..45d7cb002e0b 100644 --- a/src/main/webapp/app/exercises/text/manage/tutor-effort/tutor-effort-statistics.component.ts +++ b/src/main/webapp/app/exercises/text/manage/tutor-effort/tutor-effort-statistics.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { TutorEffort } from 'app/entities/tutor-effort.model'; import { TextExerciseService } from 'app/exercises/text/manage/text-exercise/text-exercise.service'; import { ActivatedRoute, Router } from '@angular/router'; @@ -21,6 +21,12 @@ interface TutorEffortRange { styleUrls: ['./tutor-effort-statistics.component.scss'], }) export class TutorEffortStatisticsComponent extends PlagiarismAndTutorEffortDirective implements OnInit { + private route = inject(ActivatedRoute); + private router = inject(Router); + private textExerciseService = inject(TextExerciseService); + private textAssessmentService = inject(TextAssessmentService); + private translateService = inject(TranslateService); + tutorEfforts: TutorEffort[] = []; numberOfSubmissions: number; totalTimeSpent: number; @@ -43,13 +49,7 @@ export class TutorEffortStatisticsComponent extends PlagiarismAndTutorEffortDire // Icons faSync = faSync; - constructor( - private textExerciseService: TextExerciseService, - private textAssessmentService: TextAssessmentService, - private route: ActivatedRoute, - private translateService: TranslateService, - private router: Router, - ) { + constructor() { super(); this.translateService.onLangChange.subscribe(() => { this.translateLabels(); diff --git a/src/main/webapp/app/exercises/text/participate/text-editor.component.ts b/src/main/webapp/app/exercises/text/participate/text-editor.component.ts index 94659dfc211d..81deae339df6 100644 --- a/src/main/webapp/app/exercises/text/participate/text-editor.component.ts +++ b/src/main/webapp/app/exercises/text/participate/text-editor.component.ts @@ -1,5 +1,4 @@ -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { TranslateService } from '@ngx-translate/core'; +import { Component, Input, OnDestroy, OnInit, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { HttpErrorResponse } from '@angular/common/http'; import { AlertService } from 'app/core/util/alert.service'; @@ -34,7 +33,7 @@ import { ProfileService } from 'app/shared/layouts/profiles/profile.service'; import { PROFILE_IRIS } from 'app/app.constants'; import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service'; import { AssessmentType } from 'app/entities/assessment-type.model'; -import { CourseExerciseService } from 'app/exercises/shared/course-exercises/course-exercise.service'; + @Component({ selector: 'jhi-text-editor', templateUrl: './text-editor.component.html', @@ -42,6 +41,16 @@ import { CourseExerciseService } from 'app/exercises/shared/course-exercises/cou styleUrls: ['./text-editor.component.scss'], }) export class TextEditorComponent implements OnInit, OnDestroy, ComponentCanDeactivate { + private route = inject(ActivatedRoute); + private textSubmissionService = inject(TextSubmissionService); + private textService = inject(TextEditorService); + private alertService = inject(AlertService); + private participationWebsocketService = inject(ParticipationWebsocketService); + private stringCountService = inject(StringCountService); + private accountService = inject(AccountService); + private profileService = inject(ProfileService); + private irisSettingsService = inject(IrisSettingsService); + readonly ButtonType = ButtonType; readonly MAX_CHARACTER_COUNT = MAX_SUBMISSION_TEXT_LENGTH; protected readonly Result = Result; @@ -64,7 +73,7 @@ export class TextEditorComponent implements OnInit, OnDestroy, ComponentCanDeact resultWithComplaint?: Result; submission: TextSubmission; course?: Course; - isSaving: boolean; + isSaving: boolean = false; private textEditorInput = new Subject(); textEditorInputObservable = this.textEditorInput.asObservable(); private submissionChange = new Subject(); @@ -96,22 +105,6 @@ export class TextEditorComponent implements OnInit, OnDestroy, ComponentCanDeact showHistory: boolean = false; submissionId: number | undefined; - constructor( - private route: ActivatedRoute, - private textSubmissionService: TextSubmissionService, - private textService: TextEditorService, - private alertService: AlertService, - private translateService: TranslateService, - private participationWebsocketService: ParticipationWebsocketService, - private stringCountService: StringCountService, - private accountService: AccountService, - private courseExerciseService: CourseExerciseService, - private profileService: ProfileService, - private irisSettingsService: IrisSettingsService, - ) { - this.isSaving = false; - } - ngOnInit() { if (this.inputValuesArePresent()) { this.setupComponentWithInputValues(); diff --git a/src/main/webapp/app/exercises/text/participate/text-editor.service.ts b/src/main/webapp/app/exercises/text/participate/text-editor.service.ts index cf7d67767a0a..5c87204ace41 100644 --- a/src/main/webapp/app/exercises/text/participate/text-editor.service.ts +++ b/src/main/webapp/app/exercises/text/participate/text-editor.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, tap } from 'rxjs'; import { francAll } from 'franc-min'; @@ -8,7 +8,7 @@ import { ExerciseService } from 'app/exercises/shared/exercise/exercise.service' @Injectable({ providedIn: 'root' }) export class TextEditorService { - constructor(private http: HttpClient) {} + private http = inject(HttpClient); get(participationId: number): Observable { return this.http diff --git a/src/main/webapp/app/exercises/text/participate/text-result/text-result.component.ts b/src/main/webapp/app/exercises/text/participate/text-result/text-result.component.ts index c63aaece1335..00fdd151b73b 100644 --- a/src/main/webapp/app/exercises/text/participate/text-result/text-result.component.ts +++ b/src/main/webapp/app/exercises/text/participate/text-result/text-result.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { Feedback, buildFeedbackTextForReview, checkSubsequentFeedbackInAssessment } from 'app/entities/feedback.model'; import { TextSubmission } from 'app/entities/text/text-submission.model'; import { Result } from 'app/entities/result.model'; @@ -15,6 +15,9 @@ import { Course } from 'app/entities/course.model'; styleUrls: ['./text-result.component.scss'], }) export class TextResultComponent { + private translateService = inject(TranslateService); + private localeConversionService = inject(LocaleConversionService); + public submissionText: string; public textResults: TextResultBlock[]; @@ -40,11 +43,6 @@ export class TextResultComponent { @Input() course?: Course; - constructor( - private translateService: TranslateService, - private localeConversionService: LocaleConversionService, - ) {} - private convertTextToResultBlocks(feedbacks: Feedback[] = []): void { checkSubsequentFeedbackInAssessment(feedbacks); diff --git a/src/main/webapp/app/exercises/text/participate/text-submission.service.ts b/src/main/webapp/app/exercises/text/participate/text-submission.service.ts index 2c90d0c7188c..7d406b3fe8d3 100644 --- a/src/main/webapp/app/exercises/text/participate/text-submission.service.ts +++ b/src/main/webapp/app/exercises/text/participate/text-submission.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -12,10 +12,8 @@ export type EntityResponseType = HttpResponse; @Injectable({ providedIn: 'root' }) export class TextSubmissionService { - constructor( - private http: HttpClient, - private submissionService: SubmissionService, - ) {} + private http = inject(HttpClient); + private submissionService = inject(SubmissionService); create(textSubmission: TextSubmission, exerciseId: number): Observable { const copy = this.submissionService.convert(textSubmission); diff --git a/src/main/webapp/app/exercises/text/shared/manual-text-selection/manual-text-selection.component.ts b/src/main/webapp/app/exercises/text/shared/manual-text-selection/manual-text-selection.component.ts index 1a846ba58988..b7c83334e01e 100644 --- a/src/main/webapp/app/exercises/text/shared/manual-text-selection/manual-text-selection.component.ts +++ b/src/main/webapp/app/exercises/text/shared/manual-text-selection/manual-text-selection.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, inject } from '@angular/core'; import { TextAssessmentEventType } from 'app/entities/text/text-assesment-event.model'; import { FeedbackType } from 'app/entities/feedback.model'; import { TextBlockType } from 'app/entities/text/text-block.model'; @@ -21,6 +21,9 @@ const SPACE = ' '; styleUrls: ['./manual-text-selection.component.scss'], }) export class ManualTextSelectionComponent { + protected route = inject(ActivatedRoute); + textAssessmentAnalytics = inject(TextAssessmentAnalytics); + @Input() public textBlockRefGroup: TextBlockRefGroup; @Input() submission: TextSubmission; @Output() public didSelectWord = new EventEmitter(); @@ -33,11 +36,8 @@ export class ManualTextSelectionComponent { public selectedWords = new Array(); public ready = false; - constructor( - public textAssessmentAnalytics: TextAssessmentAnalytics, - protected route: ActivatedRoute, - ) { - textAssessmentAnalytics.setComponentRoute(route); + constructor() { + this.textAssessmentAnalytics.setComponentRoute(this.route); } calculateIndex(index: number): void { diff --git a/src/main/webapp/app/exercises/text/shared/text-select.directive.ts b/src/main/webapp/app/exercises/text/shared/text-select.directive.ts index 3ff564df7462..8ead1a2d74ee 100644 --- a/src/main/webapp/app/exercises/text/shared/text-select.directive.ts +++ b/src/main/webapp/app/exercises/text/shared/text-select.directive.ts @@ -1,4 +1,4 @@ -import { Directive, ElementRef, EventEmitter, NgZone, OnDestroy, OnInit, Output } from '@angular/core'; +import { Directive, ElementRef, EventEmitter, NgZone, OnDestroy, OnInit, Output, inject } from '@angular/core'; /** * Disclaimer: @@ -32,15 +32,13 @@ enum EventType { selector: '[jhiTextSelect]', }) export class TextSelectDirective implements OnInit, OnDestroy { + private elementRef = inject(ElementRef); + private zone = inject(NgZone); + @Output() public jhiTextSelect = new EventEmitter(); private hasSelection = false; - constructor( - private elementRef: ElementRef, - private zone: NgZone, - ) {} - /** * Init text select directive by adding event listenes mouseDown and selectionChange event listeners to element. */ diff --git a/src/test/javascript/spec/service/text-editor.service.spec.ts b/src/test/javascript/spec/service/text-editor.service.spec.ts index 4171441cdcc0..c701dad2f618 100644 --- a/src/test/javascript/spec/service/text-editor.service.spec.ts +++ b/src/test/javascript/spec/service/text-editor.service.spec.ts @@ -1,21 +1,19 @@ import { TextEditorService } from 'app/exercises/text/participate/text-editor.service'; -import { HttpClient, HttpEvent, HttpHandler } from '@angular/common/http'; -import { Observable } from 'rxjs'; +import { provideHttpClient } from '@angular/common/http'; import { Language } from 'app/entities/course.model'; - -class MockHttpHandler implements HttpHandler { - handle(): Observable> { - return new Observable>(); - } -} +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { TestBed } from '@angular/core/testing'; describe('TextEditorService', () => { let textEditorService: TextEditorService; - let httpClient: HttpClient; + beforeEach(() => { - httpClient = new HttpClient(new MockHttpHandler()); - textEditorService = new TextEditorService(httpClient); + TestBed.configureTestingModule({ + imports: [], + providers: [provideHttpClient(), provideHttpClientTesting()], + }); + textEditorService = TestBed.inject(TextEditorService); }); it('Can detect a short German string', () => { const testString = 'Das ist ein kurzer, deutscher Satz';