Skip to content
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

Development: Migrate exercise group client code to signals #10332

Merged
merged 37 commits into from
Feb 17, 2025

Conversation

coolchock
Copy link
Contributor

@coolchock coolchock commented Feb 15, 2025

Checklist

General

Client

Description

This pull request migrates exercise group module to signals, inject and standalone

Steps for Testing

Prerequisites:

  • 1 Instructor
  1. Log in to Artemis
  2. Navigate to Course Administration -> Exams -> Selected Exam -> Exercise Groups
  3. Create an exercise group which contains programming, modeling, quiz, text and file upload exercise.
  4. Verify that all rows are displayed properly

Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Summary by CodeRabbit

Summary by CodeRabbit

  • Refactor
    • Streamlined the exam management interface to ensure a consistent and reliable display of exercise details across file upload, modeling, programming, and quiz exercises. This update leads to a more predictable and smoother experience when managing exam exercises.
    • Updated input handling for exercise components to use a more modern Angular approach, enhancing consistency and simplifying data access.

# Conflicts:
#	src/main/webapp/app/exam/manage/exercise-groups/exercise-group-update.component.ts
#	src/main/webapp/app/exam/manage/exercise-groups/exercise-groups.component.ts
#	src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.ts
#	src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts
#	src/main/webapp/app/exercises/shared/exam-exercise-row-buttons/exam-exercise-row-buttons.component.ts
#	src/test/javascript/spec/component/exam/manage/exam-exercise-row-buttons.component.spec.ts
#	src/test/javascript/spec/component/exam/manage/exercise-groups/exercise-group-update.component.spec.ts
#	src/test/javascript/spec/component/exam/manage/exercise-groups/exercise-group.service.spec.ts
#	src/test/javascript/spec/component/exam/manage/exercise-groups/file-upload-exercise-group-cell.component.spec.ts
#	src/test/javascript/spec/component/exam/manage/exercise-groups/modeling-exercise-group-cell.component.spec.ts
#	src/test/javascript/spec/component/exam/manage/exercise-groups/programming-exercise-group-cell.component.spec.ts
#	src/test/javascript/spec/component/exam/manage/exercise-groups/quiz-exercise-group-cell.component.spec.ts
@coolchock coolchock requested a review from a team as a code owner February 15, 2025 11:05
@coolchock coolchock changed the title Chore/exercise groups client migration General: Migrate exercise group module to signals Feb 15, 2025
@github-actions github-actions bot added tests client Pull requests that update TypeScript code. (Added Automatically!) labels Feb 15, 2025
Copy link

coderabbitai bot commented Feb 15, 2025

Walkthrough

This PR refactors several Angular exercise group cell components and their corresponding tests. The changes replace direct property accesses and setter methods with calls to an exercise() function and use input.required<T>() for input property declarations. Consequently, HTML templates and TypeScript files for file-upload, modeling, programming, and quiz exercises now uniformly access exercise data via function calls rather than direct properties. Tests have been updated to use fixture.componentRef.setInput for input binding, and unused mocks have been removed from some test files.

Changes

File(s) Change Summary
src/main/webapp/app/exam/manage/exercise-groups/.../file-upload-exercise-group-cell.component.html
src/main/webapp/app/exam/manage/exercise-groups/.../modeling-exercise-group-cell.component.html
src/main/webapp/app/exam/manage/exercise-groups/.../programming-exercise-group-cell.component.html
src/main/webapp/app/exam/manage/exercise-groups/.../quiz-exercise-group-cell.component.html
Updated HTML templates to replace direct property checks (e.g., fileUploadExercise, modelingExercise, etc.) with calls to exercise() for accessing data such as type, file pattern, diagram type, and display flags.
src/main/webapp/app/exam/manage/exercise-groups/.../file-upload-exercise-group-cell.component.ts
src/main/webapp/app/exam/manage/exercise-groups/.../modeling-exercise-group-cell.component.ts
src/main/webapp/app/exam/manage/exercise-groups/.../programming-exercise-group-cell.component.ts
src/main/webapp/app/exam/manage/exercise-groups/.../quiz-exercise-group-cell.component.ts
Refactored component TS files by replacing the @Input() setter methods and private property assignments with direct declarations using input.required<T>(), and updated import statements to use input (lowercase).
src/test/javascript/spec/component/... Revised test files to standardize input assignment using fixture.componentRef.setInput instead of direct component property assignment. Unused mock imports were removed and dependency injection (e.g., for NgbModal) was updated.

Sequence Diagram(s)

sequenceDiagram
    participant Angular
    participant Component
    participant Template
    Angular->>Component: Initialize component
    Angular->>Component: Bind input using input.required<T>()
    Component->>Template: Expose exercise() for data access
    Template->>Component: Call exercise() to retrieve properties (e.g., type, filePattern)
Loading

Possibly related PRs

Suggested labels

ready to merge, maintainer-approved


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c99f095 and dc044d4.

📒 Files selected for processing (3)
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.html (2 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts (3 hunks)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/programming-exercise-group-cell.component.spec.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/programming-exercise-group-cell.component.spec.ts
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.html
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Call Build Workflow / Build and Push Docker Image
  • GitHub Check: Call Build Workflow / Build .war artifact
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: server-tests
  • GitHub Check: client-tests-selected
  • GitHub Check: client-style
  • GitHub Check: client-tests
  • GitHub Check: server-style
  • GitHub Check: Analyse

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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

@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: 1

🔭 Outside diff range comments (3)
src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts (2)

41-59: 🛠️ Refactor suggestion

Prevent memory leaks and improve code readability.

The profile service subscription should be cleaned up on component destruction, and the nested optional chaining could be simplified.

Apply these improvements:

+    private destroy$ = new Subject<void>();

     ngOnInit(): void {
-        this.profileService.getProfileInfo().subscribe((profileInfo) => {
+        this.profileService.getProfileInfo().pipe(
+            takeUntil(this.destroy$)
+        ).subscribe((profileInfo) => {
             this.localVCEnabled = profileInfo.activeProfiles.includes(PROFILE_LOCALVC);
             this.onlineIdeEnabled = profileInfo.activeProfiles.includes(PROFILE_THEIA);

-            const projectKey = this.exercise()?.projectKey;
-            if (projectKey) {
-                const solutionParticipation = this.exercise()?.solutionParticipation;
+            const exercise = this.exercise();
+            if (exercise?.projectKey) {
+                const { solutionParticipation, templateParticipation } = exercise;
                 if (solutionParticipation?.buildPlanId) {
-                    solutionParticipation.buildPlanUrl = createBuildPlanUrl(profileInfo.buildPlanURLTemplate, projectKey, solutionParticipation.buildPlanId);
+                    solutionParticipation.buildPlanUrl = createBuildPlanUrl(
+                        profileInfo.buildPlanURLTemplate,
+                        exercise.projectKey,
+                        solutionParticipation.buildPlanId
+                    );
                 }

-                const templateParticipation = this.exercise()?.templateParticipation;
                 if (templateParticipation?.buildPlanId) {
-                    templateParticipation.buildPlanUrl = createBuildPlanUrl(profileInfo.buildPlanURLTemplate, projectKey, templateParticipation.buildPlanId);
+                    templateParticipation.buildPlanUrl = createBuildPlanUrl(
+                        profileInfo.buildPlanURLTemplate,
+                        exercise.projectKey,
+                        templateParticipation.buildPlanId
+                    );
                 }
             }
         });
     }

+    ngOnDestroy(): void {
+        this.destroy$.next();
+        this.destroy$.complete();
+    }

61-77: 🛠️ Refactor suggestion

Add error handling and prevent memory leaks in HTTP call.

The HTTP subscription should be cleaned up and error cases should be handled.

Apply these improvements:

     downloadRepository(repositoryType: ProgrammingExerciseInstructorRepositoryType): void {
         const programmingExerciseId = this.exercise()?.id;
         if (programmingExerciseId) {
-            this.programmingExerciseService.exportInstructorRepository(programmingExerciseId, repositoryType, undefined).subscribe((response: HttpResponse<Blob>) => {
-                downloadZipFileFromResponse(response);
-                this.alertService.success('artemisApp.programmingExercise.export.successMessageRepos');
-            });
+            this.programmingExerciseService.exportInstructorRepository(programmingExerciseId, repositoryType, undefined).pipe(
+                take(1)
+            ).subscribe({
+                next: (response: HttpResponse<Blob>) => {
+                    downloadZipFileFromResponse(response);
+                    this.alertService.success('artemisApp.programmingExercise.export.successMessageRepos');
+                },
+                error: (error) => {
+                    this.alertService.error('artemisApp.programmingExercise.export.errorMessageRepos', error.message);
+                }
+            });
         }
     }
src/test/javascript/spec/component/exam/manage/exercise-groups/programming-exercise-group-cell.component.spec.ts (1)

103-114: 🛠️ Refactor suggestion

Add error handling test for repository download.

The download repository test only covers the success case. Add tests for error scenarios.

Add error handling test:

it('should handle repository download error', () => {
    // GIVEN
    const error = new Error('Download failed');
    const exportRepositoryStub = jest.spyOn(mockProgrammingExerciseService, 'exportInstructorRepository')
        .mockReturnValue(throwError(() => error));
    const alertErrorStub = jest.spyOn(mockAlertService, 'error');

    // WHEN
    comp.downloadRepository('TEMPLATE');

    // THEN
    expect(exportRepositoryStub).toHaveBeenCalledOnce();
    expect(alertErrorStub).toHaveBeenCalledOnce();
    expect(alertErrorStub).toHaveBeenCalledWith(
        'artemisApp.programmingExercise.export.errorMessageRepos',
        error.message
    );
});
🧹 Nitpick comments (11)
src/main/webapp/app/exam/manage/exercise-groups/quiz-exercise-cell/quiz-exercise-group-cell.component.ts (1)

1-1: LGTM! Migration to required inputs improves type safety.

The changes align with Angular's new input APIs, providing better type safety and simpler code structure by removing the need for private backing fields and setter methods.

Consider adding a comment explaining that this component is standalone, as it's not immediately obvious from the current code. This helps other developers understand the component's architecture.

Also applies to: 12-12

src/test/javascript/spec/component/exam/manage/exercise-groups/quiz-exercise-group-cell.component.spec.ts (2)

17-27: Improve test assertions using recommended patterns.

The test assertions could be more specific as per guidelines.

Apply this diff to improve the assertions:

 it('should display number of quiz questions', () => {
     const exercise: QuizExercise = {
         id: 1,
         type: ExerciseType.QUIZ,
         quizQuestions: [{}, {}],
     } as any as QuizExercise;
     fixture.componentRef.setInput('exercise', exercise);

     fixture.detectChanges();
-    expect(fixture.nativeElement.textContent).toContain('2');
+    expect(fixture.nativeElement.textContent.includes('2')).toBeTrue();
 });

29-39: Improve negative test case assertions.

The negative test case could be more specific.

Apply this diff to improve the assertions:

 it('should not display anything for other exercise types', () => {
     const exercise: QuizExercise = {
         id: 1,
         type: ExerciseType.TEXT,
         quizQuestions: [{}, {}],
     } as any as QuizExercise;
     fixture.componentRef.setInput('exercise', exercise);

     fixture.detectChanges();
-    expect(fixture.nativeElement.textContent).toBe('');
+    expect(fixture.nativeElement.textContent.trim()).toBe('');
 });
src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts (1)

1-38: LGTM! Modern Angular patterns well implemented.

The migration to standalone components and signal-based inputs is well executed. The component properly declares its dependencies and uses type-safe inputs.

Consider grouping related inputs together and adding JSDoc comments for better documentation:

+    /** Display-related configuration inputs */
     displayShortName = input(false);
     displayRepositoryUri = input(false);
     displayTemplateUrls = input(false);
     displayEditorModus = input(false);
+    /** Core exercise data input */
     exercise = input.required<ProgrammingExercise>();
src/test/javascript/spec/component/exam/manage/exercise-groups/file-upload-exercise-group-cell.component.spec.ts (1)

1-40: LGTM! Tests follow modern Angular patterns.

The migration to using setInput for component inputs is well implemented. However, consider adding error case tests.

Add test for error handling:

it('should handle invalid file pattern gracefully', () => {
    const exercise: FileUploadExercise = {
        id: 1,
        type: ExerciseType.FILE_UPLOAD,
        filePattern: undefined,
    } as any as FileUploadExercise;
    fixture.componentRef.setInput('exercise', exercise);
    fixture.detectChanges();
    expect(fixture.nativeElement.textContent).toBe('');
});
src/test/javascript/spec/component/exam/manage/exercise-groups/modeling-exercise-group-cell.component.spec.ts (1)

1-42: LGTM! Tests follow modern Angular patterns.

The migration to using setInput and proper test module setup is well implemented. However, consider adding more edge case tests.

Add tests for edge cases:

it('should handle undefined diagram type gracefully', () => {
    const exercise: ModelingExercise = {
        id: 1,
        type: ExerciseType.MODELING,
        diagramType: undefined,
    } as any as ModelingExercise;
    fixture.componentRef.setInput('exercise', exercise);
    fixture.detectChanges();
    expect(fixture.nativeElement.textContent).toBe('');
});

it('should handle null exercise gracefully', () => {
    fixture.componentRef.setInput('exercise', null);
    fixture.detectChanges();
    expect(fixture.nativeElement.textContent).toBe('');
});
src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.html (5)

1-2: Top-Level Conditional Checks and Function Calls:
The refactored conditionals now call exercise() and displayShortName() instead of directly referencing a component variable. This promotes consistency across the template. If these functions are more than light getters, consider caching their results in a local template variable to avoid redundant calls during change detection cycles.


7-24: Template Participation Repository Block:
The block handling the template participation details consistently replaces direct property accesses with function calls (e.g., exercise().templateParticipation?.repositoryUri). The use of optional chaining and the non-null assertion in [participation]="exercise().templateParticipation!" appears safe provided the conditional check (line 10) guarantees the presence of the property. This results in cleaner, more maintainable code.


30-44: Solution Participation Block:
The changes for the solution participation section mirror those in the template block. Using expressions like exercise().solutionParticipation?.repositoryUri and [participation]="exercise().solutionParticipation!" ensures consistency and safe access. Just be sure that the non-null assertions are indeed safe given the preceding conditions.


60-83: Template URLs Block:
This block appropriately displays the build plan links or IDs for template and solution participations based on the availability of a build plan ID. The use of non-null assertions (e.g., exercise().templateParticipation!) is acceptable here as long as the conditions guarantee that these properties exist.


84-101: Editor Mode Block:
The rendering logic for offline and online editor modes is now driven by the displayEditorModus() function, with subsequent data accessed via exercise(). Conditional translations for allowOfflineIde, allowOnlineEditor, and allowOnlineIde are handled cleanly. As with earlier sections, evaluate whether repeatedly invoking exercise() might benefit from caching if any performance issues arise.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e48b7e and c99f095.

📒 Files selected for processing (14)
  • src/main/webapp/app/exam/manage/exercise-groups/file-upload-exercise-cell/file-upload-exercise-group-cell.component.html (1 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/file-upload-exercise-cell/file-upload-exercise-group-cell.component.ts (2 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.html (1 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.ts (2 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.html (2 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts (3 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/quiz-exercise-cell/quiz-exercise-group-cell.component.html (1 hunks)
  • src/main/webapp/app/exam/manage/exercise-groups/quiz-exercise-cell/quiz-exercise-group-cell.component.ts (2 hunks)
  • src/test/javascript/spec/component/exam-exercise-row-buttons/exam-exercise-row-buttons.component.spec.ts (1 hunks)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/exercise-groups.component.spec.ts (4 hunks)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/file-upload-exercise-group-cell.component.spec.ts (1 hunks)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/modeling-exercise-group-cell.component.spec.ts (1 hunks)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/programming-exercise-group-cell.component.spec.ts (3 hunks)
  • src/test/javascript/spec/component/exam/manage/exercise-groups/quiz-exercise-group-cell.component.spec.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/test/javascript/spec/component/exam-exercise-row-buttons/exam-exercise-row-buttons.component.spec.ts
🧰 Additional context used
📓 Path-based instructions (3)
`src/main/webapp/**/*.html`: @if and @for are new and valid ...

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/exam/manage/exercise-groups/file-upload-exercise-cell/file-upload-exercise-group-cell.component.html
  • src/main/webapp/app/exam/manage/exercise-groups/quiz-exercise-cell/quiz-exercise-group-cell.component.html
  • src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.html
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.html
`src/test/javascript/spec/**/*.ts`: jest: true; mock: NgMock...

src/test/javascript/spec/**/*.ts: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}

  • src/test/javascript/spec/component/exam/manage/exercise-groups/quiz-exercise-group-cell.component.spec.ts
  • src/test/javascript/spec/component/exam/manage/exercise-groups/modeling-exercise-group-cell.component.spec.ts
  • src/test/javascript/spec/component/exam/manage/exercise-groups/programming-exercise-group-cell.component.spec.ts
  • src/test/javascript/spec/component/exam/manage/exercise-groups/file-upload-exercise-group-cell.component.spec.ts
  • src/test/javascript/spec/component/exam/manage/exercise-groups/exercise-groups.component.spec.ts
`src/main/webapp/**/*.ts`: angular_style:https://angular.io/...

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/exam/manage/exercise-groups/quiz-exercise-cell/quiz-exercise-group-cell.component.ts
  • src/main/webapp/app/exam/manage/exercise-groups/file-upload-exercise-cell/file-upload-exercise-group-cell.component.ts
  • src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.ts
  • src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: client-tests
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: Analyse
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (8)
src/main/webapp/app/exam/manage/exercise-groups/file-upload-exercise-cell/file-upload-exercise-group-cell.component.ts (1)

1-1: LGTM! Consistent implementation with other components.

The changes maintain consistency with the quiz component's implementation, following the same pattern for required inputs.

Also applies to: 12-12

src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.ts (1)

1-1: LGTM! Well-structured standalone component.

The changes maintain consistency with other components while properly declaring dependencies through imports.

Also applies to: 14-14

src/test/javascript/spec/component/exam/manage/exercise-groups/exercise-groups.component.spec.ts (1)

51-59: Great improvements to the test setup!

The changes enhance the test configuration by:

  • Using standalone components in the imports array
  • Leveraging MockProvider for better mocking
  • Using overrideProvider for dependency injection
  • Using fixture.debugElement.injector.get for service retrieval

Also applies to: 68-68

src/main/webapp/app/exam/manage/exercise-groups/file-upload-exercise-cell/file-upload-exercise-group-cell.component.html (1)

1-2: Excellent use of Angular's new control flow syntax!

The changes demonstrate best practices by:

  • Using @if instead of *ngIf
  • Using function calls for data access
  • Providing a fallback with the || operator
src/main/webapp/app/exam/manage/exercise-groups/quiz-exercise-cell/quiz-exercise-group-cell.component.html (1)

1-2: Great use of safe navigation operators!

The changes demonstrate best practices by:

  • Using @if instead of *ngIf
  • Using optional chaining (?.) for safe property access
  • Providing a fallback with the || operator
src/main/webapp/app/exam/manage/exercise-groups/modeling-exercise-cell/modeling-exercise-group-cell.component.html (1)

1-2: Great use of Angular's new control flow syntax and translation pipe!

The changes demonstrate best practices by:

  • Using @if instead of *ngIf
  • Using function calls for data access
  • Using the artemisTranslate pipe for internationalization
src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.html (2)

4-4: Interpolation Binding for Short Name:
Using the interpolation expression {{ exercise().shortName || '' }} correctly provides a fallback in case shortName is null or undefined.


48-57: Test Repository URI Block:
The conditional checking for exercise().testRepositoryUri is straightforward and effectively controls the display of the test repository link. This section adheres to the new approach for fetching exercise details.

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 15, 2025
HawKhiem
HawKhiem previously approved these changes Feb 15, 2025
Copy link

@HawKhiem HawKhiem left a comment

Choose a reason for hiding this comment

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

Tested on TS4. All rows are displayed correctly

image

# Conflicts:
#	src/main/webapp/app/exam/manage/exercise-groups/programming-exercise-cell/programming-exercise-group-cell.component.ts
@coolchock coolchock dismissed stale reviews from HawKhiem and coderabbitai[bot] via dc044d4 February 15, 2025 14:30
Copy link
Contributor

@ole-ve ole-ve left a comment

Choose a reason for hiding this comment

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

code is pretty straightforward, not too much to say about this (have already reviewed the "old PR")

@helios-aet helios-aet bot temporarily deployed to artemis-test6.artemis.cit.tum.de February 16, 2025 10:42 Inactive
Copy link

@HawKhiem HawKhiem left a comment

Choose a reason for hiding this comment

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

Tested on TS6. Reapprove

Copy link
Member

@BBesrour BBesrour left a comment

Choose a reason for hiding this comment

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

code

@helios-aet helios-aet bot temporarily deployed to artemis-test2.artemis.cit.tum.de February 16, 2025 21:11 Inactive
Copy link

@HanyangXu0508 HanyangXu0508 left a comment

Choose a reason for hiding this comment

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

Tested on Server 2 and worked well.
IMG_3652

@krusche krusche changed the title General: Migrate exercise group module to signals Development: Migrate exercise group client code to signals Feb 17, 2025
@krusche krusche added this to the 7.10.2 milestone Feb 17, 2025
@krusche krusche merged commit 696d645 into develop Feb 17, 2025
44 of 46 checks passed
@krusche krusche deleted the chore/exercise-groups-client-migration branch February 17, 2025 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client Pull requests that update TypeScript code. (Added Automatically!) ready to merge small tests
Projects
Status: Merged
Development

Successfully merging this pull request may close these issues.

6 participants