Skip to content

Development: Migrate assessment module client to angular decoratorless API #10860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from

Conversation

maximiliansoelch
Copy link
Member

@maximiliansoelch maximiliansoelch commented May 14, 2025

Checklist

General

Client

Motivation and Context

Description

With this PR, the majority of the components are migrated to use signals instead of @input, @output, @ViewChild, etc.

Steps for Testing

Note

The changes in this PR affect a lot of different components relevant for assessment. The provided testing steps only cover the main assessment functionality, but there could be workflows not covered by them. Please also think about other possible testing steps yourself when testing.

Exercise Assessment (Text / Modeling / Programming / File Upload)

Preconditions:

  • 1 Instructor
  • 1 Student
  • 1 Exercise of each type: Text, Modeling, Programming, and File Upload
  • Add SGI (Structured Grading Instructions) to the exercises
  • Complaints enabled

Steps:

  1. Participate in each exercise as a student.
  2. As a tutor or instructor, assess one submission per exercise type.
    ✅ Expected:
    • Assessment views render correctly.
    • Feedback can be added and saved.
    • Submissions can be submitted or updated without errors.
    • SGIs can be applied via drag-and-drop on feedback elements inline or as general feedback
  3. For modeling exercises: use the graphical editor to assess individual model elements
  4. For programming exercises: ensure inline feedback works in code editor.
  5. For text exercises: make sure you can provide feedback on whole sentences or specific text ranges
  6. Submit a complaint and handle it as an instructor/tutor.
    ✅ Expected: Complaint UI is functional and response can be saved successfully.

Structured Grading Instructions (SGIs)

Steps:

  1. Open any text or modeling exercise that includes SGIs.
  2. Apply SGIs during assessment.
    ✅ Expected: Applied SGIs reflect in the feedback list and affect the score correctly.

Assessment Statistics and Feedback Requests

Steps:

  1. Go to the Assessment Dashboard of the course.
  2. Open the Statistics page and the Complaints / More Feedback Requests overviews.
    ✅ Expected: All values and links render correctly and navigate to valid submissions.

Grading Key

  1. Go to the Assessment Dashboard
  2. Click on Grading Key
  3. Set the total points for the course
  4. Generate a grading key
    ✅ Expected: Creation, customization, and saving of grading keys is possible. Also, deleting it should still be possible.

Exam Mode Testing

Preconditions:

  • 1 Instructor
  • 2 Students
  • 1 Exam with a Programming, Modeling, and Text Exercise

Steps:

  1. Students participate in the exam.
  2. After the exam ends, assess each submission as instructor/tutor.
    ✅ Expected: Assessment UI behaves identically to course mode. No layout bugs or interaction regressions. Complaints should also work as expected.

Testserver States

You can manage test servers using Helios. Check environment statuses in the environment list. To deploy to a test server, go to the CI/CD page, find your PR or branch, and trigger the deployment.

Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Exam Mode Test

  • Test 1
  • Test 2

Test Coverage

Unchanged

Summary by CodeRabbit

  • New Features

    • No new user-facing features were added in this release.
  • Refactor

    • All components now use a new reactive input/output API, replacing traditional Angular decorators for input and output properties. Inputs and outputs are now accessed as functions, improving consistency and enabling more reactive data handling.
    • Templates and internal logic have been updated to invoke inputs and outputs as functions rather than properties.
    • Event emitters and model properties have been migrated to the new API for more predictable state management.
    • Several method and event signatures were simplified, removing unused parameters.
  • Bug Fixes

    • No direct bug fixes were included, but the refactor may improve reliability in input and output handling.
  • Tests

    • Test suites have been updated to set component inputs using Angular’s recommended input binding methods, ensuring better alignment with the framework’s lifecycle.
    • Test assertions and mocks were adapted to the new input/output API and access patterns.
  • Style

    • Minor updates to templates for consistency, such as using function calls for all bindings.
  • Chores

    • Removed unused imports and updated import statements to match the new API usage.

@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development May 14, 2025
@github-actions github-actions bot added client Pull requests that update TypeScript code. (Added Automatically!) assessment Pull requests that affect the corresponding module labels May 14, 2025
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report201 ran197 passed3 skipped1 failed59m 13s 875ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure1m 47s 126ms

Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ✅Skipped ⚠️FailedTime ⏱
End-to-End (E2E) Test Report201 ran198 passed3 skipped0 failed52m 51s 206ms
TestResultTime ⏱
No test annotations available

Copy link

End-to-End (E2E) Test Results Summary

@helios-aet helios-aet bot temporarily deployed to artemis-test3.artemis.cit.tum.de May 15, 2025 17:50 Inactive
@github-actions github-actions bot added atlas Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module labels May 15, 2025
Copy link

End-to-End (E2E) Test Results Summary

Copy link

End-to-End (E2E) Test Results Summary

@maximiliansoelch maximiliansoelch marked this pull request as ready for review May 16, 2025 09:07
@maximiliansoelch maximiliansoelch requested review from a team and krusche as code owners May 16, 2025 09:07
@maximiliansoelch maximiliansoelch moved this from Work In Progress to Ready For Review in Artemis Development May 16, 2025
Copy link
Contributor

coderabbitai bot commented May 16, 2025

Walkthrough

This update refactors a large set of Angular components to use the new standalone reactive input/output API (input, output, model, viewChildren) instead of the classic @Input()/@Output()/EventEmitter decorators. All component templates and TypeScript files are updated to access these properties as functions (e.g., inputProp()), and test files now set inputs using setInput on the component reference. Some event payloads are simplified, and all usages of component inputs/outputs are adapted to the new API, with no changes to business logic or control flow.

Changes

File(s) Change Summary
.../assessment-complaint-alert/assessment-complaint-alert.component.{ts,html,spec.ts} Refactored input property to use input() API; updated template to use local variable and function access; tests now set input via setInput.
.../assessment-header/assessment-header.component.{ts,html,spec.ts} All inputs/outputs refactored to input()/output()/model() API; template and tests updated to use function calls and setInput.
.../assessment-instructions/assessment-instructions/assessment-instructions.component.{ts,html} Inputs refactored to input()/model(); template updated to call methods as functions.
.../assessment-instructions/assessment-instructions/collapsable-assessment-instructions.component.{ts,html,spec.ts} Inputs refactored to input()/model(); template and tests updated to use function calls and setInput.
.../assessment-instructions/expandable-section/expandable-section.component.{ts,html,spec.ts} Inputs refactored to input(); template and tests updated to use function calls and setInput.
.../assessment-layout/assessment-layout.component.{ts,html,spec.ts} Inputs/outputs refactored to input()/output(); template and tests updated to use function calls and setInput.
.../assessment-note/assessment-note.component.ts Output refactored to use output() API.
.../assessment-warning/assessment-warning.component.{ts,spec.ts} Inputs refactored to input(); tests updated to use setInput.
.../complaint-response/complaint-response.component.{ts,html} Inputs refactored to input.required(); template updated to use local variable and function calls.
.../complaints-for-tutor/complaints-for-tutor.component.{ts,html,spec.ts} Inputs/outputs refactored to input()/model()/output(); template and tests updated to use function calls and setInput.
.../grading-system/grading-key/grading-key-table.component.{ts,html,spec.ts} Inputs refactored to model(); template and tests updated to use function calls and .set() for updates.
.../rating/star-rating/star-rating.component.ts Output refactored to use output(); emitted event payload simplified.
.../structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.{ts,html,spec.ts} Inputs refactored to input(); view children refactored to viewChildren(); template and tests updated to use function calls and setInput.
.../unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.{ts,html} Inputs refactored to input(); template updated to use function calls.
.../unreferenced-feedback-detail/unreferenced-feedback-detail.component.{ts,html,spec.ts} Inputs/outputs refactored to input()/model()/output(); template and tests updated to use function calls and setInput.
.../overview/complaint-form/complaints-form.component.{ts,html,spec.ts} Inputs/outputs refactored to input()/output(); template and tests updated to use function calls and setInput.
.../overview/complaint-request/complaint-request.component.{ts,html} Inputs refactored to input.required(); template updated to use function calls.
.../overview/complaints-for-students/complaint-student-view.component.spec.ts Tests updated to use setInput for all component inputs; DOM mock updated for scroll point.
.../overview/complaints-for-students/complaints-student-view.component.{ts,html} Inputs refactored to input(); template and all logic updated to use function calls; replaced ViewChild with Renderer2 for DOM access.
.../shared/assessment-dashboard/assessment-dashboard-information.component.{ts,html,spec.ts} Inputs refactored to input(); template and tests updated to use function calls and setInput.
.../shared/assessment-dashboard/exercise-dashboard/language-table-cell/language-table-cell.component.ts Input refactored to input(); derived property now computed; template updated to use function call.
.../shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.{ts,html} Inputs/outputs refactored to input()/output(); template updated to use function calls.
.../shared/info-panel/info-panel.component.{ts,html} Inputs refactored to input(); template updated to use function call.
.../atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating.component.{ts,spec.ts} Event parameter type for onRate simplified; tests updated accordingly.
.../exercise/rating/rating.component.{ts,spec.ts} Event parameter type for onRate simplified; tests updated accordingly.

Sequence Diagram(s)

sequenceDiagram
  participant ParentComponent
  participant ChildComponent

  Note over ParentComponent,ChildComponent: New Reactive Input/Output API

  ParentComponent->>ChildComponent: [inputProp]="value" (template)
  Note right of ChildComponent: inputProp declared via input()/model()
  ChildComponent-->>ParentComponent: value accessed as inputProp()
  ParentComponent->>ChildComponent: (outputEvent)="handler()" (template)
  Note right of ChildComponent: outputEvent declared via output()
  ChildComponent-->>ParentComponent: outputEvent.emit(data)
Loading
sequenceDiagram
  participant Test
  participant ComponentFixture
  participant Component

  Test->>ComponentFixture: setInput('inputName', value)
  ComponentFixture->>Component: updates reactive input
  Note right of Component: input accessed as inputName()
  Test->>ComponentFixture: detectChanges()
  Component->>Component: uses inputName() in logic/template
Loading
sequenceDiagram
  participant Component
  participant Template

  Template->>Component: Calls inputProp() for value
  Template->>Component: Calls outputEvent.emit(data) for events
Loading

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🔭 Outside diff range comments (3)
src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.ts (1)

84-87: 🛠️ Refactor suggestion

Prefer template reference or ViewChild over direct document.querySelector

Manipulating the DOM via document.querySelector bypasses Angular’s change-detection and is hard to unit-test. Consider binding the <textarea> to a template reference (#complainText) and reading its .value.length, or expose the length directly through [(ngModel)].

-        const textArea: HTMLTextAreaElement = document.querySelector('#complainTextArea') as HTMLTextAreaElement;
-        return textArea.value.length;
+        // e.g. using a template reference variable
+        return this.complaintText?.length ?? 0;
src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.ts (1)

32-55: ⚠️ Potential issue

Detach interact.js listeners on destroy to prevent memory leaks

interact('.expanded-instructions')… registers global listeners but they are never removed. On repeated navigation this can cause duplicated handlers and leaks.

@@
 export class CollapsableAssessmentInstructionsComponent implements AfterViewInit, OnDestroy {
@@
     ngAfterViewInit(): void {
-        interact('.expanded-instructions')
+        this.interactable = interact('.expanded-instructions')
             .resizable({ … });
     }
+
+    private interactable?: ReturnType<typeof interact>;
+
+    ngOnDestroy(): void {
+        this.interactable?.unset();   // clean-up
+    }

Remember to add implements OnDestroy in the class declaration and import it from @angular/core.

src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.ts (1)

90-101: ⚠️ Potential issue

Null-safety check before locking a complaint.

this.complaint().id! assumes both the complaint and its id exist.
Add a guard clause to avoid 500 responses or crashes when the id is missing:

- this.complaintResponseService
-     .createLock(this.complaint().id!)
+const complaint = this.complaint();
+if (!complaint?.id) {
+    this.alertService.error('artemisApp.complaint.missingId');
+    return;
+}
+this.complaintResponseService
+     .createLock(complaint.id)
🧹 Nitpick comments (23)
src/main/webapp/app/assessment/manage/assessment-note/assessment-note.component.ts (1)

15-25: Consider migrating the input property to the decoratorless API for consistency.

While you've successfully migrated the output property to use the new reactive API, the assessmentNote input property still uses the traditional @Input decorator with setter/getter pattern. For consistency with the rest of the codebase migration, consider refactoring this to use the model() API which supports two-way binding:

readonly assessmentNote = model<AssessmentNote>(new AssessmentNote());

// Remove the setter/getter and instead update your component to use assessmentNote() and assessmentNote.set()

Alternatively, if you need the same logic in the setter, you could use:

private _assessmentNoteInternal = signal<AssessmentNote>(new AssessmentNote());
readonly assessmentNote = input<AssessmentNote | undefined>({
  transform: (value) => {
    if (value === undefined) {
      this._assessmentNoteInternal.set(new AssessmentNote());
    } else {
      this._assessmentNoteInternal.set(value);
    }
    return value;
  }
});

// And use _assessmentNoteInternal() to access the value
src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.html (1)

86-102: Consider simplifying conditional rendering with @if/@else

The template uses multiple separate @if blocks with mutually exclusive conditions that could be simplified.

Consider refactoring to use the more concise @if/@else pattern:

@if (feedback().correctionStatus !== undefined) {
    <div>
-       @if (feedback().correctionStatus === 'CORRECT') {
-           <span class="text-success">{{ 'artemisApp.exampleSubmission.feedback.' + feedback().correctionStatus! | artemisTranslate }} </span>
-       }
-       @if (feedback().correctionStatus !== 'CORRECT') {
-           <span class="text-danger">{{ 'artemisApp.exampleSubmission.feedback.' + feedback().correctionStatus! | artemisTranslate }} </span>
-       }
+       @if (feedback().correctionStatus === 'CORRECT') {
+           <span class="text-success">{{ 'artemisApp.exampleSubmission.feedback.' + feedback().correctionStatus! | artemisTranslate }} </span>
+       } @else {
+           <span class="text-danger">{{ 'artemisApp.exampleSubmission.feedback.' + feedback().correctionStatus! | artemisTranslate }} </span>
+           <!-- :warning: emoji was rendered as a black-white glyph, hence the solution with the fa-icon -->
+           <fa-layers>
+               <fa-icon class="text-warning" [icon]="faExclamationTriangle" />
+               <fa-icon class="text-dark exclamation-icon" [icon]="faExclamation" size="2x" transform="shrink-10" />
+           </fa-layers>
+       }
-       <!-- :warning: emoji was rendered as a black-white glyph, hence the solution with the fa-icon -->
-       @if (feedback().correctionStatus !== 'CORRECT') {
-           <fa-layers>
-               <fa-icon class="text-warning" [icon]="faExclamationTriangle" />
-               <fa-icon class="text-dark exclamation-icon" [icon]="faExclamation" size="2x" transform="shrink-10" />
-           </fa-layers>
-       }
    </div>
}
src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.spec.ts (1)

51-51: Remove redundant input setting

This line is redundant as the same input is already set in the beforeEach block.

-fixture.componentRef.setInput('exercise', exercise);
src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.spec.ts (1)

59-60: Remove redundant isExamMode input setting

The isExamMode input is already set to false in the beforeEach block, making this line redundant.

-fixture.componentRef.setInput('isExamMode', false);
 fixture.componentRef.setInput('examId', 42);
src/main/webapp/app/assessment/overview/complaints-for-students/complaint-student-view.component.spec.ts (3)

170-171: Simplified DOM element mocking approach

Good improvement on the DOM element mocking strategy by directly assigning the mock function to the DOM element instead of creating an ElementRef. This is cleaner and more straightforward.

Consider adding a null check before assigning the scrollIntoView function to handle potential cases where the element might not be found:

-fixture.nativeElement.querySelector('#complaintScrollpoint').scrollIntoView = scrollIntoViewMock;
+const scrollElement = fixture.nativeElement.querySelector('#complaintScrollpoint');
+if (scrollElement) {
+    scrollElement.scrollIntoView = scrollIntoViewMock;
+}

262-263: Same DOM mocking approach used consistently

The same simplified DOM element mocking strategy is used here, which is good for consistency, but the same null check recommendation applies.

See suggestion from previous comment about adding a null check.


286-287: Consistent DOM mocking approach

Same simplified DOM element mocking strategy is used consistently throughout the tests.

See suggestion from previous comments about adding a null check.

src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.html (1)

9-23: Consider using a local template variable for frequently accessed values.

The numberOfSubmissions().total is called multiple times in the template. For better performance, consider storing it in a local template variable:

-@if (numberOfSubmissions().total !== 0) {
+@if (numberOfSubmissions(); as submissions) {
+@if (submissions.total !== 0) {
    <div class="pie-chart pb-2" style="margin-top: -10px">
        <ngx-charts-pie-chart
            [customColors]="customColors"
            [view]="view"
            [results]="assessments"
            [legend]="true"
            [legendTitle]="''"
            [legendPosition]="legendPosition"
            [animations]="false"
        >
-            <ng-template #tooltipTemplate let-model="model"> {{ ((model.value * 100) / this.numberOfSubmissions().total).toFixed(2) }}% </ng-template>
+            <ng-template #tooltipTemplate let-model="model"> {{ ((model.value * 100) / submissions.total).toFixed(2) }}% </ng-template>
        </ngx-charts-pie-chart>
    </div>
}
src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.ts (1)

56-58: Use optional chaining for safer property access.

The reduce operation could benefit from optional chaining for safer property access:

return this.submissions()
    .map((submission) => submission.participation?.individualDueDate)
-    .reduce((latest, next) => (next && next.isAfter(latest) ? next : latest), this.exercise().dueDate);
+    .reduce((latest, next) => (next && next?.isAfter(latest) ? next : latest), this.exercise().dueDate);

This addresses the static analysis hint and prevents potential errors if next is defined but isAfter is not a method on it.

🧰 Tools
🪛 Biome (1.9.4)

[error] 58-58: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.ts (2)

38-45: Avoid re-invoking signal accessors inside the same method

this.exercise() is called three times inside ngOnInit. Although signal access is cheap, reading it once and re-using the local reference improves readability and avoids surprises if the accessor ever becomes reactive.

-        this.course = getCourseFromExercise(this.exercise());
+        const exercise = this.exercise();   // single read
+        this.course = getCourseFromExercise(exercise);
         this.maxComplaintTextLimit = this.course?.maxComplaintTextLimit ?? 0;
-        const exercise = this.exercise();

55-60: Guard against undefined examId to keep payload minimal

examId is optional. If it is undefined, adding the field to the DTO serialises it as null, which might break strict-null REST contracts.

-        complaintRequest.examId = this.examId();
+        const examId = this.examId();
+        if (examId !== undefined) {
+            complaintRequest.examId = examId;
+        }
src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.ts (3)

1-1: Mixing decorator-less API with classic @Input() – deliberate but be consistent

The file now uses both input()/output() and an @Input() setter (highlightDifferences).
That is perfectly valid when two-way binding of a primitive is required, but please keep the dual approach documented for future maintainers.


56-58: Consider initial value for _highlightDifferences

_highlightDifferences is boolean but never initialised, so it starts as undefined, which could leak into consumers before the first setter call. Initialising to false is safer.

-    private _highlightDifferences: boolean;
+    private _highlightDifferences = false;

98-106: Minor readability: cache result() call

result() is invoked repeatedly inside the same getter. Storing it locally improves readability.

-        const result = this.result();
-        if (result?.completionDate) {
+        const res = this.result();
+        if (res?.completionDate) {
             return true;
-        } else if (Result.hasNonEmptyAssessmentNote(result)) {
+        } else if (Result.hasNonEmptyAssessmentNote(res)) {
src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html (2)

27-82: Consider extracting complex ‑and duplicate- conditions into computed helpers.

The block contains 7 highly-nested @if statements that repeat the same signal calls (isAssessor(), hasComplaint(), complaintType(), exercise.assessmentType, exercise.teamMode, …).
Besides reducing readability, every call re-evaluates the signal getter during change detection.

Suggestion (illustrative):

readonly showMoreFeedbackRequest = computed(() =>
    isAssessor() &&
    !exercise().isAtLeastInstructor &&
    hasComplaint() &&
    complaintType() !== ComplaintType.COMPLAINT &&
    !complaintHandled() &&
    exercise().assessmentType !== AssessmentType.AUTOMATIC,
);

The template then becomes:

@if (showMoreFeedbackRequest()) {
    <span id="moreFeedbackRequest" ></span>
}

This removes duplication, shortens the template and avoids unnecessary signal look-ups.


88-102: Minor: group busy-state checks into a single helper to avoid repetition.

[disabled]="saveBusy() || submitBusy() || cancelBusy()" (and similar) is repeated for several buttons.
A small computed helper (anyBusy()) or a readonly busy = computed(() => …) would centralize the logic and prevent future divergence.

src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts (1)

1-1: Avoid mixing classic @Input() with the new signal-based API for the same data source.

The file imports both Input and the new input/model helpers, and keeps exercise as a classic setter while all other inputs are signals.
For consistency and to prevent two different change-detection paths, migrate exercise to input.required<Exercise>() (plus a computed() view model), or keep all inputs decorator-based until the full component is migrated.

src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.ts (2)

35-41: Mark required inputs as such to avoid unnecessary non-null assertions.

exercise, submission, and especially complaint are accessed with ! later (exercise()!, complaint().id!).
Declare them with input.required<T>() (or model.required) so the compiler enforces presence and you can drop the bang operator:

-readonly exercise = input<Exercise>();
+readonly exercise = input.required<Exercise>();

171-179: complaint().complaintType is accessed without null checks.

Inside the acceptance branch the signal is called multiple times.
Cache the complaint once, or use the already-available variable from the guard above to avoid inconsistencies and extra calls.

src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.ts (1)

53-60: Consider migrating the remaining highlightDifferences property to decoratorless API.

While most properties have been migrated to the new API, highlightDifferences still uses the traditional @Input decorator. This creates an inconsistency in the component's API style.

-@Input() set highlightDifferences(highlightDifferences: boolean) {
-    this._highlightDifferences = highlightDifferences;
-    this.highlightDifferencesChange.emit(this.highlightDifferences);
-}
-
-get highlightDifferences() {
-    return this._highlightDifferences;
-}
+readonly highlightDifferences = model<boolean>(false, {
+   transform: (value) => {
+     this.highlightDifferencesChange.emit(value);
+     return value;
+   }
+});
src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.ts (3)

42-48: Provide defaults for optional boolean inputs
isSuggestion is declared as input<boolean>() without a default value, resulting in undefined when the attribute is omitted. The template often treats it as a boolean flag, so undefinedfalsy may look okay, but it complicates strict type checks (strictNullChecks).

-readonly isSuggestion = input<boolean>();
+// default to false to avoid undefined checks everywhere
+readonly isSuggestion = input<boolean>(false);

Same argument applies to highlightDifferences. Giving it an explicit default (false) is already done – nice job!


49-53: Unify access-modifiers & align with naming convention
You mix public readonly (lines 49-50) with readonly (lines 51-52). The signals are already immutable references; “public” adds no value because the class is exported. A consistent modifier set improves readability.

-public readonly onFeedbackChange = output<Feedback>();
-public readonly onFeedbackDelete = output<Feedback>();
-readonly onAcceptSuggestion = output<Feedback>();
-readonly onDiscardSuggestion = output<Feedback>();
+readonly onFeedbackChange = output<Feedback>();
+readonly onFeedbackDelete = output<Feedback>();
+readonly onAcceptSuggestion = output<Feedback>();
+readonly onDiscardSuggestion = output<Feedback>();

109-112: Call preventDefault() when hijacking a drop event
event.stopPropagation() prevents bubbling but still lets the browser execute its default action (e.g. opening a link when files are dropped). Adding preventDefault() ensures no accidental navigation occurs.

-event.stopPropagation();
+event.preventDefault();
+event.stopPropagation();
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 43a3f12 and a07f8c0.

📒 Files selected for processing (57)
  • src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.html (1 hunks)
  • src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.spec.ts (1 hunks)
  • src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html (5 hunks)
  • src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.spec.ts (13 hunks)
  • src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.ts (6 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.html (4 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts (3 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.html (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.spec.ts (1 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.html (1 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.spec.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.ts (3 hunks)
  • src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.html (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.spec.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.ts (3 hunks)
  • src/main/webapp/app/assessment/manage/assessment-note/assessment-note.component.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.spec.ts (3 hunks)
  • src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.ts (3 hunks)
  • src/main/webapp/app/assessment/manage/complaint-response/complaint-response.component.html (1 hunks)
  • src/main/webapp/app/assessment/manage/complaint-response/complaint-response.component.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.html (5 hunks)
  • src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.spec.ts (9 hunks)
  • src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.ts (11 hunks)
  • src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.html (1 hunks)
  • src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.spec.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.ts (4 hunks)
  • src/main/webapp/app/assessment/manage/rating/star-rating/star-rating.component.ts (3 hunks)
  • src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.html (2 hunks)
  • src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.spec.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.html (1 hunks)
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.html (3 hunks)
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.spec.ts (2 hunks)
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.ts (3 hunks)
  • src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.html (3 hunks)
  • src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.spec.ts (4 hunks)
  • src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.ts (4 hunks)
  • src/main/webapp/app/assessment/overview/complaint-request/complaint-request.component.html (1 hunks)
  • src/main/webapp/app/assessment/overview/complaint-request/complaint-request.component.ts (2 hunks)
  • src/main/webapp/app/assessment/overview/complaints-for-students/complaint-student-view.component.spec.ts (21 hunks)
  • src/main/webapp/app/assessment/overview/complaints-for-students/complaints-student-view.component.html (2 hunks)
  • src/main/webapp/app/assessment/overview/complaints-for-students/complaints-student-view.component.ts (7 hunks)
  • src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.html (4 hunks)
  • src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.spec.ts (4 hunks)
  • src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.ts (4 hunks)
  • src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/language-table-cell/language-table-cell.component.ts (1 hunks)
  • src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.html (1 hunks)
  • src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.ts (2 hunks)
  • src/main/webapp/app/assessment/shared/info-panel/info-panel.component.html (1 hunks)
  • src/main/webapp/app/assessment/shared/info-panel/info-panel.component.ts (1 hunks)
  • src/main/webapp/app/atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating-component.spec.ts (2 hunks)
  • src/main/webapp/app/atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating.component.ts (1 hunks)
  • src/main/webapp/app/exercise/rating/rating.component.spec.ts (0 hunks)
  • src/main/webapp/app/exercise/rating/rating.component.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/webapp/app/exercise/rating/rating.component.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
`src/main/webapp/**/*.ts`: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalC...

src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

  • src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.spec.ts
  • src/main/webapp/app/assessment/overview/complaints-for-students/complaint-student-view.component.spec.ts
  • src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.ts
  • src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.ts
  • src/main/webapp/app/atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating-component.spec.ts
  • src/main/webapp/app/assessment/manage/assessment-note/assessment-note.component.ts
  • src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.spec.ts
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.spec.ts
  • src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.spec.ts
  • src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.spec.ts
  • src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.spec.ts
  • src/main/webapp/app/atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating.component.ts
  • src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.spec.ts
  • src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.spec.ts
  • src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.spec.ts
  • src/main/webapp/app/assessment/shared/info-panel/info-panel.component.ts
  • src/main/webapp/app/exercise/rating/rating.component.ts
  • src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.spec.ts
  • src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.ts
  • src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.spec.ts
  • src/main/webapp/app/assessment/manage/rating/star-rating/star-rating.component.ts
  • src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.spec.ts
  • src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.ts
  • src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/language-table-cell/language-table-cell.component.ts
  • src/main/webapp/app/assessment/manage/complaint-response/complaint-response.component.ts
  • src/main/webapp/app/assessment/overview/complaint-request/complaint-request.component.ts
  • src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.ts
  • src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.ts
  • src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.ts
  • src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.ts
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.ts
  • src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.ts
  • src/main/webapp/app/assessment/overview/complaints-for-students/complaints-student-view.component.ts
  • src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.ts
  • src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.ts
  • src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.ts
  • src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.ts
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.ts
`src/main/webapp/**/*.html`: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

  • src/main/webapp/app/assessment/shared/info-panel/info-panel.component.html
  • src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.html
  • src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html
  • src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.html
  • src/main/webapp/app/assessment/overview/complaints-for-students/complaints-student-view.component.html
  • src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.html
  • src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.html
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.html
  • src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.html
  • src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.html
  • src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.html
  • src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.html
  • src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.html
  • src/main/webapp/app/assessment/manage/complaint-response/complaint-response.component.html
  • src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.html
  • src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.html
  • src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.html
  • src/main/webapp/app/assessment/overview/complaint-request/complaint-request.component.html
🪛 Biome (1.9.4)
src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.ts

[error] 58-58: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (128)
src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/language-table-cell/language-table-cell.component.ts (1)

1-1: Well-executed migration to Angular decoratorless API!

The component has been successfully refactored to use Angular's new reactive primitives instead of traditional decorators. The changes align perfectly with the PR objective of modernizing the codebase:

  1. Replaced @Input() decorator with input.required<Submission>()
  2. Created a computed property for derived state
  3. Updated the template to use function call syntax for accessing reactive values

These changes improve type safety and make reactivity more explicit while maintaining the same component behavior.

Also applies to: 8-8, 12-13

src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.html (1)

3-3: Good use of new Angular control flow syntax.

The migration from *ngIf to @if and property access to method calls (secondCorrectionEnabled() and togglingSecondCorrectionButton()) correctly implements Angular's modern control flow syntax and aligns with the reactive input pattern.

Also applies to: 6-6, 12-12, 15-15

src/main/webapp/app/assessment/shared/assessment-dashboard/exercise-dashboard/second-correction-button/second-correction-enable-button.component.ts (3)

1-1: Correct import updates for decoratorless API.

The imports have been properly updated to include input and output from '@angular/core' for the reactive API.


13-14: Properly implemented reactive inputs.

The input properties have been correctly converted from @Input() decorators to the new reactive input<boolean>() API, maintaining their functionality while modernizing the implementation.


16-16: Properly implemented reactive output.

The output has been correctly converted from @Output() decorator with EventEmitter to the new reactive output() API, maintaining the same event emission functionality.

src/main/webapp/app/assessment/shared/info-panel/info-panel.component.html (1)

3-3: Good implementation of the decoratorless API pattern.

The template correctly uses function call syntax panelHeader() instead of property access, which aligns with the reactive input pattern being implemented. This ensures proper reactivity when the input value changes.

src/main/webapp/app/assessment/shared/info-panel/info-panel.component.ts (2)

1-1: Correctly imported the new input API.

The import statement has been properly updated to include the input function from Angular core, which is required for the decoratorless API implementation.


9-10: Well-implemented migration to decoratorless inputs.

The code properly:

  • Uses input.required<string>() for the mandatory panelHeader input
  • Uses input<string>() for the optional panelDescriptionHeader input
  • Marks both properties as readonly to prevent reassignment

This implementation follows Angular's best practices for the new reactive input API.

src/main/webapp/app/atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating-component.spec.ts (2)

93-93: LGTM! Event object simplified correctly.

The test has been updated to use the simplified event object structure that aligns with the component's updated onRate method signature, removing the unnecessary starRating property.


107-108: LGTM! Consistent event object simplification.

This change correctly maintains consistency with the prior test case and matches the component's updated event object structure.

src/main/webapp/app/atlas/overview/judgement-of-learning-rating/judgement-of-learning-rating.component.ts (1)

30-30: LGTM! Method signature simplified appropriately.

The onRate method signature has been successfully simplified to only include the necessary data (oldValue and newValue), removing the dependency on the StarRatingComponent type. This reduces coupling between components and aligns with the decoratorless API migration.

src/main/webapp/app/exercise/rating/rating.component.ts (1)

50-50: LGTM! Method signature simplified correctly.

The onRate method signature has been properly updated to use the simplified event object, consistent with other components in the codebase. This change maintains the method's functionality while reducing component coupling.

src/main/webapp/app/assessment/manage/rating/star-rating/star-rating.component.ts (3)

1-1: LGTM! Import updated for decoratorless API.

Successfully added the output function import which is needed for the decoratorless API implementation.


78-81: LGTM! Output migrated to decoratorless API.

The component has been properly updated to use the new output() function instead of the traditional @Output() decorator with EventEmitter. This aligns with the PR objective to migrate to the Angular decoratorless API.


191-192: LGTM! Event emission simplified appropriately.

The event payload has been correctly simplified to only include the essential data (oldValue and newValue), removing the redundant component instance reference. This reduces coupling and aligns with modern Angular practices.

src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.spec.ts (1)

38-38: Good migration to the Angular reactive input API

The test has been properly updated to use fixture.componentRef.setInput('complaint', complaint) instead of direct property assignment. This approach aligns with Angular's reactive input API standards and ensures that proper input lifecycle hooks are triggered during testing.

src/main/webapp/app/assessment/overview/complaints-for-students/complaints-student-view.component.html (3)

7-7: Correctly migrated property access to function call

The property access has been properly updated to use the function call syntax exercise() for the reactive input API.


54-57: Properly updated input bindings to decoratorless API

All input bindings have been correctly migrated to use the reactive function calls (exercise(), result(), exam()) with appropriate null assertions where needed.


63-63: Replaced ViewChild reference with ID-based approach

The template reference variable has been correctly replaced with an ID attribute. This change supports the migration away from ViewChild decorators to a more reactive approach using element selection by ID.

src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.html (1)

3-3: Successfully migrated to Angular reactive input API

The conditional statements have been correctly updated to call highlightDifferences() and feedback() as functions rather than accessing them as properties. This aligns with Angular's reactive input pattern.

Also applies to: 10-10

src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.html (1)

1-2: Well-executed migration to modern Angular syntax

The template has been effectively updated to:

  1. Use the new @if syntax instead of *ngIf as required per the coding guidelines
  2. Call complaint() as a function and assign its value to a local variable using as complaint
  3. Access properties directly on the local variable without optional chaining

This implementation follows modern Angular best practices and matches the decoratorless API approach being adopted throughout the codebase.

Also applies to: 5-5

src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.html (3)

1-1: Good use of new Angular control flow syntax!

You've correctly migrated from *ngIf to the new @if control flow syntax while also updating criteria to be accessed as a function call.


17-51: Good job implementing Angular's new control flow syntax!

You've correctly updated:

  1. From *ngFor to @for with the new track syntax
  2. Using $index instead of index
  3. Accessing criteria() as a function call
  4. Nested @for loop implementation is correct

These changes are aligned with Angular's new control flow syntax and the reactive API pattern.


11-16:

❌ Incorrect review comment

Check if allowDrop should be accessed as a function

While you've updated criteria to be accessed as a function call, allowDrop is still being accessed as a property. If allowDrop is implemented as a reactive input or signal in the component, it should be accessed as allowDrop().


🏁 Script executed:

#!/bin/bash
# Search for the definition of allowDrop in the component file
rg -A 3 "allowDrop" src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.ts

Length of output: 497


allowDrop is a plain boolean property, not a signal or function
The component declares

allowDrop: boolean;
ngOnInit(): void {
    this.allowDrop = !this.readonly();
}
collapseAll() {
    return this.allowDrop;
}

so accessing it as allowDrop (not allowDrop()) is correct.

Likely an incorrect or invalid review comment.

src/main/webapp/app/assessment/overview/complaint-request/complaint-request.component.html (3)

4-8: Good reactive API implementation!

You've correctly updated the template to access the complaint input as a function call complaint() for all property accesses. This aligns with Angular's new reactive API pattern.


9-17: Well implemented control flow and reactive properties!

The migration from *ngIf directives to the new @if syntax is done correctly. You're also consistently accessing the complaint() input as a function throughout the conditional blocks.


19-27: Consistent reactive input pattern for form bindings!

The form control bindings have been correctly updated to use function calls:

  1. [maxLength]="maxComplaintTextLimit()"
  2. [(ngModel)]="complaint().complaintText"

This maintains consistency with the reactive input pattern throughout the template.

src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.spec.ts (3)

21-28: Good test refactoring for reactive inputs!

You've correctly updated the test to use fixture.componentRef.setInput('exercise', ...) instead of direct property assignment. This matches the testing pattern needed for components using the reactive input API.


30-39: Consistent test input setting approach!

The test case for checking behavior before exercise due date has been properly updated to use fixture.componentRef.setInput('exercise', exercise) rather than direct property assignment.


63-65: Well-implemented test setup for multiple inputs!

You've correctly updated both inputs:

  1. fixture.componentRef.setInput('exercise', exercise)
  2. fixture.componentRef.setInput('submissions', [submission2, submission4, submission3, submission1])

This ensures proper testing of components using the reactive input API pattern.

src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.html (3)

1-6: Great implementation of reactive patterns!

You've successfully:

  1. Migrated from *ngIf to the new @if syntax
  2. Updated all input properties to be accessed as functions:
    • hasTranslation()
    • headerKey()
    • isSubHeader()
  3. Maintained consistent reactive access pattern throughout the condition

This aligns perfectly with Angular's new control flow and reactive API.


7-12: Consistent reactive property access pattern!

The second conditional block correctly implements:

  1. The new @if syntax
  2. Function call access for all input properties
  3. Properly maintains the pipe syntax with headerKey() | artemisTranslate

This demonstrates a thorough understanding of Angular's reactive API.


13-18: Well-maintained pattern throughout the template!

The third conditional section maintains consistency with the reactive pattern, accessing all input properties as functions. Great attention to detail in ensuring every input property is accessed properly.

src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.spec.ts (2)

115-115: Correct adaptation to reactive input model.

The test has been properly updated to invoke studentGradeOrBonusPointsOrGradeBonus() as a method rather than accessing it as a property, aligning with the component's migration to Angular's decoratorless API.


193-193: Correct adaptation to reactive input model.

Similar to the earlier change, this test assertion has been properly updated to invoke studentGradeOrBonusPointsOrGradeBonus() as a method, ensuring consistency throughout the test file.

src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.html (1)

14-14: Good optimization using template variable.

Using @let to cache the result of studentGradeOrBonusPointsOrGradeBonus() is an excellent optimization. This reduces redundant method calls and improves template performance by storing the value once and reusing it throughout the template's conditional logic and highlighting.

src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.spec.ts (6)

39-41: Correct implementation of input binding in tests.

The change from direct property assignment to fixture.componentRef.setInput() correctly follows Angular's recommended approach for setting inputs in component tests when using the decoratorless API.


45-46: Proper input binding for readonly property.

Using fixture.componentRef.setInput() here ensures the component's reactive input lifecycle hooks are properly triggered.


77-77: Consistent input binding approach for criteria.

Continuing the pattern of using setInput() for criteria maintains consistency with Angular's recommended testing approach.


80-81: Correct adaptation to view children as method.

The test has been properly updated to access expandableSections() as a method rather than a property, reflecting its migration from a @ViewChildren QueryList to a reactive viewChildren() function.


85-86: Consistent usage of expandableSections() as method.

The change maintains consistency in accessing expandableSections() as a method throughout the test.


89-90: Consistent usage of expandableSections() as method.

The final usage of expandableSections() is correctly updated to method invocation, ensuring consistency across the entire test file.

src/main/webapp/app/assessment/manage/complaint-response/complaint-response.component.html (2)

1-2: Excellent safe binding pattern with reactive inputs.

Using @if (complaint(); as complaint) followed by an explicit undefined check creates a robust pattern that:

  1. Properly accesses the reactive input as a method
  2. Creates a local variable for convenient access
  3. Prevents null reference errors through careful safety checks

This approach follows Angular best practices for working with the decoratorless API.


20-20: Correct adaptation to reactive method call.

The change to invoke maxComplaintResponseTextLimit() as a method properly aligns with the component's migration to the decoratorless API.

src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.spec.ts (2)

30-31: Good migration to Angular's recommended testing approach for reactive inputs.

The changes correctly update test cases to use fixture.componentRef.setInput() instead of direct property assignment when setting input values. This properly aligns with the component's migration to the decoratorless API and ensures that the input lifecycle hooks are correctly triggered during testing.

Also applies to: 39-39, 51-51


35-35: Properly adapted assertion to match the new input pattern.

The assertion has been correctly updated to reference the local headerKey variable instead of accessing it through the component, which is consistent with the reactive input pattern used throughout the PR.

src/main/webapp/app/assessment/manage/assessment-note/assessment-note.component.ts (1)

1-1: Good migration to the decoratorless API for outputs.

The change from @Output() with EventEmitter to output() function correctly implements Angular's new reactive output API.

Also applies to: 13-13

src/main/webapp/app/assessment/manage/assessment-complaint-alert/assessment-complaint-alert.component.ts (1)

1-1: Clean migration to the decoratorless API.

The component has been correctly updated to use the new reactive input() function instead of the @Input() decorator. The readonly modifier is appropriate here to prevent the signal from being reassigned.

Also applies to: 17-17

src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.html (2)

1-1: Well implemented migration to Angular's new control flow syntax.

The template correctly uses the new @if syntax instead of the older *ngIf directive, which aligns with Angular's recommended approach and the specified coding guidelines.

Also applies to: 6-6, 17-17, 24-24, 30-30


1-1: Properly updated property access for the reactive decoratorless API.

All property accesses have been correctly updated to use method calls (with parentheses) to access the values from the reactive inputs, which is required when using the new input/output API.

Also applies to: 5-5, 6-6, 8-8, 17-17, 20-20, 24-24, 26-26, 30-30, 46-46

src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.html (10)

8-9: LGTM! Property access pattern updated correctly.

The template now correctly uses function invocation for complaint() and accesses its properties, which aligns with Angular's decoratorless API using signals.


11-12: Correctly updated to use function calls.

Both complaint() and zeroIndent() are now properly invoked as functions rather than accessed as properties, following Angular's new reactive input pattern.


16-18: Template expression properly updated.

Good job converting the nested property access to use function invocation for complaint().


41-41: Function invocation pattern correctly applied.

The nested property access has been properly updated to use function invocation for complaint().


44-44: Optional chaining pattern updated correctly.

The template now correctly uses function invocation with optional chaining for complaint()?.accepted.


47-48: Property access correctly updated.

The conditional expression now properly uses function invocation for complaint().


53-53: Optional chaining updated correctly.

The template now properly uses function invocation with optional chaining for the negated condition.


64-64: Properly updated template binding.

The jhiTranslate binding now correctly uses function invocation for complaint().


80-80: Condition correctly updated to use function invocation.

The @if condition now properly uses function invocation for complaint().


106-106: Complex condition properly updated.

The nested conditions now correctly use function invocation for complaint(), both for the .accepted and .complaintType properties.

src/main/webapp/app/assessment/overview/complaint-request/complaint-request.component.ts (2)

1-1: Import correctly updated for decoratorless API.

The input import from Angular core has been correctly added to support the new decoratorless API.


17-18: Properly migrated to input.required API.

The component has been successfully migrated from @Input() decorators to the new decoratorless API using input.required<T>(), maintaining type safety and required input validation.

src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.spec.ts (2)

47-53: Properly updated test input setup.

Test inputs are now correctly set using fixture.componentRef.setInput() instead of direct property assignment, which is the recommended pattern when using Angular's new decoratorless API.


80-80: Test correctly updated for new input pattern.

The complaint input is now properly set using fixture.componentRef.setInput(), ensuring that Angular's input lifecycle hooks are respected during testing.

src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.html (4)

1-1: Correctly updated to use function invocation.

The @if directive now properly uses function invocation for collapsed().


5-5: State update correctly migrated to use .set() pattern.

The click handler now properly uses collapsed.set() instead of direct property assignment, which is the correct pattern for updating model state in Angular's decoratorless API.


14-19: Input bindings correctly updated to use function invocation.

All input bindings on the jhi-assessment-instructions component have been properly updated to use function invocation for reactive inputs:

  • [readOnly]="readOnly()"
  • [exercise]="exercise()"
  • [isAssessmentTraining]="isAssessmentTraining()"
  • [showAssessmentInstructions]="showAssessmentInstructions()"

24-24: State update correctly migrated to use .set() pattern.

The click handler in the collapsed state now properly uses collapsed.set() instead of direct property assignment.

src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.html (1)

1-104: Good job adopting the new @if syntax

The template correctly uses the new Angular @if structural directive instead of the older *ngIf syntax, which follows the provided coding guidelines.

src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.spec.ts (1)

44-47: Properly adopting the Angular reactive input testing pattern

Good job updating the test to use fixture.componentRef.setInput() instead of direct property assignment, which correctly follows Angular's input lifecycle hooks when testing components with signals.

src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.spec.ts (1)

22-23: Correctly implemented test setup for Angular signals

Great work updating the test to use Angular's recommended fixture.componentRef.setInput() method for setting input properties. This ensures proper initialization and change detection when working with signals.

Also applies to: 39-41, 71-71

src/main/webapp/app/assessment/manage/complaints-for-tutor/complaints-for-tutor.component.spec.ts (1)

54-56: Well-implemented test setup for Angular signals

Excellent work updating the test to use Angular's recommended fixture.componentRef.setInput() method for setting input properties. This approach correctly handles Angular's input lifecycle when testing components that use signals.

Also applies to: 78-79, 115-116

src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.spec.ts (4)

35-36: Good implementation of Angular's new input API in tests

The test has been properly updated to use fixture.componentRef.setInput() for setting component inputs instead of direct property assignment, which correctly follows Angular's input lifecycle hooks.


50-51: Consistent use of the new input API

Properly sets the feedback input using setInput() method, maintaining consistent usage of Angular's new reactive API across tests.


64-69: Correctly implemented reactive input pattern

The test has been updated to properly use setInput() for passing the feedback object to the component, following Angular's recommended patterns for testing components with the new decoratorless API.


76-83: Well-structured feedback object with appropriate setInput usage

The feedback object is properly structured with all required properties and correctly passed to the component using the setInput() method.

src/main/webapp/app/assessment/overview/complaints-for-students/complaint-student-view.component.spec.ts (2)

105-108: Good migration to Angular's new input API

The test initialization has been properly updated to use fixture.componentRef.setInput() for setting component inputs, which is the recommended approach for the new decoratorless API.


376-381: Good use of object literal with setInput

Properly uses an object literal with the spread operator and additional properties within the setInput() method, which is a clean and efficient approach.

src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.spec.ts (3)

26-27: Good initialization with setInput

Properly initializes the component with the required exercise input using setInput().


30-34: Well-structured input settings

The test properly sets all the required inputs using fixture.componentRef.setInput(), which is the correct approach with the new decoratorless API.


35-39: Correctly updated expectations for reactive inputs

The test expectations have been properly updated to call inputs as functions instead of accessing them as properties, which correctly reflects how inputs behave with the new decoratorless API.

src/main/webapp/app/assessment/manage/complaint-response/complaint-response.component.ts (1)

1-1: Correct import for new Angular API

The import has been updated to use input from '@angular/core' instead of the traditional Input decorator, which is required for the decoratorless API.

src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.html (1)

3-7: Correctly using the new @if syntax.

The code properly implements Angular's new control flow syntax with @if/@else replacing the older *ngIf directive, which aligns with the provided coding guidelines.

src/main/webapp/app/assessment/manage/grading-system/grading-key/grading-key-table.component.ts (4)

1-1: Correctly importing model from Angular core.

The code properly imports the model function from @angular/core for the new decoratorless API.


36-37: Successful migration to Angular's reactive model API.

The input properties have been correctly converted from @Input() decorators to reactive model<T>() wrappers, maintaining the component's state management capabilities.


57-59: Proper initialization of reactive models in ngOnInit.

The reactive models are correctly initialized using the .set() method with fallback values provided from route parameters.


88-88: Conditional logic updated to use function call syntax.

The conditional check has been properly updated to use the function call syntax this.forBonus() instead of direct property access.

src/main/webapp/app/assessment/manage/assessment-warning/assessment-warning.component.ts (3)

1-1: Correctly importing input from Angular core.

The import statement has been properly updated to use input instead of Input for the new decoratorless API.


34-35: Successful migration to input() API with proper type constraints.

The input properties have been correctly converted to use the new reactive inputs API:

  • exercise is properly marked as required using input.required<Exercise>()
  • submissions has a sensible default value with input<Submission[]>([])

47-52: Proper use of function call syntax in lifecycle hooks.

The ngOnChanges method correctly uses function call syntax to access the reactive inputs, and stores the result in a local variable for better readability.

src/main/webapp/app/assessment/manage/assessment-instructions/expandable-section/expandable-section.component.ts (3)

1-1: Correctly importing input from Angular core.

The import statement has been properly updated to use input instead of Input for the new decoratorless API.


16-18: Well-structured inputs with appropriate defaults.

The input properties have been properly migrated to use the new reactive input API:

  • headerKey is correctly marked as required with input.required<string>()
  • hasTranslation and isSubHeader have sensible default values

44-44: Getter updated to use function call syntax.

The storageKey getter has been correctly updated to use the function call syntax this.headerKey() to access the reactive input.

src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.spec.ts (4)

87-98: Good migration to setInput() for component inputs

The test setup correctly uses fixture.componentRef.setInput() to set input values, which is the recommended approach for testing components with Angular's new signal-based inputs.


107-111: Properly updated test to use setInput() for complex objects

Good job setting the exercise input with appropriate typing as Exercise. This maintains type safety while using the new input API.


117-119: Correctly handling test case setup with reactive inputs

The test case appropriately sets up component inputs using setInput() before checking component behavior.


413-422: Good handling of object mutation in tests

The test correctly updates the nested object property and then calls setInput() again to ensure the component receives the updated value. This is necessary with the reactive API since inputs are immutable.

src/main/webapp/app/assessment/manage/assessment-instructions/assessment-instructions/assessment-instructions.component.html (3)

1-2: Great use of template variable with @let syntax

The template effectively uses the modern @let syntax to store the result of the gradingCriteria() call, improving readability and performance by avoiding multiple function calls.


21-22: Good template variable usage for programmingParticipation

Creating a local template variable for programmingParticipation() follows best practices for readability and preventing repetitive function calls.


52-56: Properly updated conditional with function call

The @if directive correctly uses the function call syntax isAssessmentTraining() instead of property access, consistent with Angular's reactive input API.

src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/assessment-correction-round-badge/assessment-correction-round-badge.component.ts (1)

1-15: Correctly implemented signal-based inputs

The component has been successfully migrated to use Angular's reactive input API:

  1. Properly imports input from @angular/core
  2. Uses input.required<Feedback>() for mandatory inputs with type safety
  3. Uses input(false) to provide a default value for optional inputs
  4. Declares inputs as readonly to maintain immutability

This implementation aligns perfectly with Angular's latest best practices.

src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.html (4)

1-1: Good use of @let for complaint variable

Using the @let syntax to create a local template variable for complaint() improves template readability and performance by avoiding repetitive function calls.


3-30: Properly updated input bindings to use function calls

All input bindings have been correctly updated to use function calls (e.g., [isLoading]="isLoading()") instead of property access. This is consistent with Angular's reactive input API.


34-34: Correctly accessing result with function call

The binding [assessmentNote]="result()?.assessmentNote" properly uses the function call syntax to access the result input.


36-46: Well-structured complaint-related bindings

The conditional rendering of the complaints form appropriately uses the local template variable and function calls for input bindings, making the template more readable and maintainable.

src/main/webapp/app/assessment/overview/complaint-form/complaints-form.component.ts (1)

25-30: Decorator-less inputs/outputs are correctly declared – nice!

The migration to input.*()/output() is syntactically correct, strongly-typed, and improves testability.
No follow-up required here.

src/main/webapp/app/assessment/manage/assessment-instructions/collapsable-assessment-instructions/collapsable-assessment-instructions.component.ts (1)

17-21: Good use of model() for two-way collapsed state

The conversion of collapsed to a reactive model keeps external inputs intact while still allowing internal updates through .set().
No issues spotted.

src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.ts (1)

35-40: Excellent signal typing and default values

All critical flags (isLoading, saveBusy, …) are declared with input.required<T>(), ensuring the template fails fast if forgotten.

src/main/webapp/app/assessment/manage/assessment-header/assessment-header.component.html (1)

13-15: Verify that hasAssessmentDueDatePassed is a writable signal.

hasAssessmentDueDatePassed() is used for reading, while (close)="hasAssessmentDueDatePassed.set(false)" mutates it.
If the field is declared with input() instead of model(), the .set() call will raise a type error at compile-time.

Please ensure it is declared via model<boolean>() (or another writable-signal factory) in the component class.

src/main/webapp/app/assessment/manage/assessment-layout/assessment-layout.component.ts (4)

1-1: Imports updated correctly for Angular decoratorless API.

The import statement now includes input and output from '@angular/core', which are required for using Angular's new reactive input/output API.


29-49: Input properties successfully migrated to decoratorless API.

All input properties have been correctly converted to use Angular's new reactive input API with input() and input.required() functions, maintaining the same functionality while enabling Angular's new reactive paradigm.


62-67: Property access correctly updated for reactive API.

The access to result property has been correctly updated to use function call syntax this.result() to retrieve the value from the reactive input.


69-77: Output properties successfully migrated to decoratorless API.

All output properties have been correctly converted to use Angular's new reactive output API with output() functions, maintaining the same event emission functionality.

src/main/webapp/app/assessment/overview/complaints-for-students/complaints-student-view.component.ts (5)

1-1: Imports updated correctly for Angular decoratorless API.

The import statement now includes input and Renderer2 from '@angular/core', which are required for using Angular's new reactive input API and safer DOM manipulation.


36-36: Added Renderer2 for safer DOM manipulation.

Using the Renderer2 service instead of direct DOM access through ViewChild is a better practice for DOM manipulation in Angular, providing better abstraction and TestBed compatibility.


38-43: Input properties successfully migrated to decoratorless API.

All input properties have been correctly converted to use Angular's new reactive input API with input() and input.required() functions, maintaining the same functionality.


64-95: Property access correctly updated for reactive API.

The property access has been properly updated to use function call syntax (e.g., this.exercise(), this.participation()) to retrieve values from reactive inputs.


173-173: Improved DOM access using Renderer2.

The implementation now uses this.renderer.selectRootElement instead of direct DOM access via ViewChild, which is safer and more aligned with Angular best practices for DOM manipulation.

src/main/webapp/app/assessment/shared/assessment-dashboard/assessment-dashboard-information.component.ts (4)

1-1: Imports updated correctly for Angular decoratorless API.

The import statement now includes input from '@angular/core', which is required for using Angular's new reactive input API.


45-64: Input properties successfully migrated to decoratorless API.

All input properties have been correctly converted to use Angular's new reactive input API with input() and input.required() functions, maintaining the same functionality while enabling Angular's new reactive paradigm.


113-119: Property access correctly updated for reactive API.

The property access in the setupLinks method has been properly updated to use function call syntax (e.g., this.isExamMode(), this.course().id) to retrieve values from reactive inputs.


125-134: Property access correctly updated in mathematical expressions.

The property access within the graph data setup has been correctly updated to use function call syntax when accessing reactive inputs in mathematical expressions, ensuring proper reactivity.

src/main/webapp/app/assessment/manage/structured-grading-instructions-assessment-layout/structured-grading-instructions-assessment-layout.component.ts (5)

3-3: Imports updated correctly for Angular decoratorless API.

The import statement now includes input and viewChildren from '@angular/core', which are required for using Angular's new reactive input and view children API.


19-20: Input properties successfully migrated to decoratorless API.

The input properties have been correctly converted to use Angular's new reactive input API with input.required() and input() functions.


27-27: ViewChildren successfully migrated to decoratorless API.

The traditional ViewChildren decorator has been properly replaced with the new viewChildren() function, maintaining the same functionality while enabling Angular's new reactive paradigm.


33-33: Property access correctly updated for reactive API.

The property access in the ngOnInit method has been properly updated to use function call syntax (this.readonly()) to retrieve the value from the reactive input.


37-50: Property access correctly updated for view children API.

The access to expandable sections has been correctly updated to use function call syntax (this.expandableSections()) to retrieve the query list from the reactive view children.

src/main/webapp/app/assessment/manage/unreferenced-feedback-detail/unreferenced-feedback-detail.component.ts (1)

1-1: Import is correct – watch for upcoming API rename
input, output and especially model are still marked experimental in Angular 17. Keep an eye on the Angular 18 migration guide, because model is very likely to be renamed to modelSignal (RFC-16) and the current import will become deprecated.

Please double-check the next Angular pre-release notes to avoid a breaking change during the next upgrade.

Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report201 ran197 passed3 skipped1 failed54m 16s 321ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure1m 50s 325ms

@helios-aet helios-aet bot temporarily deployed to artemis-test3.artemis.cit.tum.de May 19, 2025 20:56 Inactive
Copy link
Collaborator

@MaximilianAnzinger MaximilianAnzinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atlas related changes lgtm

Copy link

There hasn't been any activity on this pull request recently. Therefore, this pull request has been automatically marked as stale and will be closed if no further activity occurs within seven days. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assessment Pull requests that affect the corresponding module atlas Pull requests that affect the corresponding module client Pull requests that update TypeScript code. (Added Automatically!) exercise Pull requests that affect the corresponding module stale
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.

2 participants