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

Programming exercises: Enhance filtering and sorting for error analysis #9315

Conversation

az108
Copy link
Contributor

@az108 az108 commented Sep 13, 2024

Checklist

General

Client

  • Important: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data.
  • I strictly followed the client coding and design guidelines.
  • Following the theming guidelines, I specified colors only in the theming variable files and checked that the changes look consistent in both the light and the dark theme.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
  • I added authorities to all new routes and checked the course groups for displaying navigation elements (links, buttons).
  • I documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.
  • I translated all newly inserted strings into English and German.

Motivation and Context

Instructors should have clear insights into why specific tests are failing. Such insights facilitate a
deeper understanding of both internal errors and student mistakes, empowering instructors to rectify errors in exercises.
Having a deeper understanding of such errors leads to high-quality feedback, enabling students to identify faulty portions
of their code and understand why certain parts do not work as expected. As a result, a smoother and more intuitive workflow, enhancing the learning experience for both instructors and students. Creating an easy-to-access visualization of common mistakes made by students, organized by occurrence, helps instructors identify misunderstandings and refine their teaching methods.

Description

This is a follow-up to #9213, where filtering, sorting, and pagination were added to the table. Long feedback texts are now truncated, with an option to view the full details in a modal. You can sort the table by clicking on column headers (except task and error category), toggle between ascending and descending order, use the search bar to filter results, and navigate through pages using pagination. Additionally a filter modal was added which allows the instructor to filter according to task, testcase or set a specific occurrence.
Additionally, the code has been refactored to align with the latest Angular guidelines, now using signals.
This PR was tested on a Course with 1500 test students and no performance issues were found.
By using the BaseAPIService class we also ensure that while using the search functionality we do not directly send a request to the server but rather wait a short decay. This ensures that we do not overwhelm the server if we spam type.

Before:
image

After:
image
image
image

Steps for Testing

Prerequisites:

  • 1 Instructor
  • Student Sumbissions
  • 1 Programming Exercise
  1. Log in to Artemis
  2. Navigate to a Course with Instructor rights
  3. Create a Programming Exercise or use an existing one
  4. Solve the Programming Exercise as Students, ideally with different kinds of Progress (You can use artemis test users for this)
  5. Navigate as Instructor to the Grading of an Exercise
  6. Navigate to the Feedback Analysis section
  7. Verify that the table displays data correctly, allowing you to search and sort and filter as expected. Ensure that long feedback texts are truncated (this can be achieved by adding or manupilating one testcase), and confirm that the modals displays all information accurately.

Testserver States

Note

These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.







Review Progress

Performance Review

  • I (as a reviewer) confirm that the client changes (in particular related to REST calls and UI responsiveness) are implemented with a very good performance
  • I (as a reviewer) confirm that the server changes (in particular related to database calls) are implemented with a very good performance

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Class/File Line Coverage Confirmation (expect)
feedback-analysis.component.ts 98%
feedback-analysis.service.ts 100%
feedback-filter-modal.component.ts 93%
feedback-modal.component.ts 100%
Methods in ResultService 91%
Methods in ResultResource 100%
FeedbackDetailDTO 100%
FeedbackAnalysisResponseDTO 100%

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a feedback filter modal for enhanced filtering of tasks and test cases.
    • Added a feedback modal to display detailed feedback analysis with improved layout and translatable content.
    • Implemented pagination and filtering capabilities in the feedback analysis component, allowing for dynamic data handling.
  • Enhancements

    • Improved user interface localization with updated translation keys for feedback and filter functionalities.
    • Enhanced feedback retrieval process with structured responses and additional metadata.
  • Bug Fixes

    • Streamlined error handling and data loading processes in the feedback analysis component.

@az108 az108 self-assigned this Sep 13, 2024
@az108 az108 requested a review from a team as a code owner September 13, 2024 19:08
@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) labels Sep 13, 2024
Copy link

coderabbitai bot commented Sep 13, 2024

Walkthrough

The changes in this pull request introduce a new feedback filtering feature within a programming exercise application. This includes the creation of two new Angular components: FeedbackFilterModalComponent for filtering feedback and FeedbackModalComponent for displaying feedback details. The FeedbackAnalysisComponent has been updated to utilize reactive programming features, enhancing its interactivity. Additionally, the FeedbackAnalysisService has been modified to support new filtering and pagination capabilities, and the corresponding DTOs and service methods have been adjusted to accommodate these changes.

Changes

File Path Change Summary
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-filter-modal.component.html New HTML template for the feedback filter modal, including form groups for filtering tasks and test cases, with a range slider for occurrence counts.
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-filter-modal.component.ts Introduced FeedbackFilterModalComponent, implementing reactive state management and filter logic. Added FilterData interface and methods for applying and clearing filters.
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html New HTML template for the feedback modal, displaying feedback analysis details with a translatable title and structured content.
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts Introduced FeedbackModalComponent with an input property for feedback details and modal management functionality.
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts Updated FeedbackAnalysisComponent to use reactive programming, replacing OnInit with reactive properties for pagination and sorting. Enhanced methods for loading data and managing feedback details.
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts Added FeedbackAnalysisResponse interface, updated FeedbackDetail interface, and introduced a new search method for retrieving feedback with pagination and filtering options. Removed getFeedbackDetailsForExercise method.
src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts Updated test suite for FeedbackAnalysisComponent to reflect new reactive methods and properties. Added tests for new functionalities including pagination and modal interactions.
src/test/javascript/spec/component/programming-exercise/feedback-analysis/modals/feedback-filter-modal.component.spec.ts Established a new test suite for FeedbackFilterModalComponent, covering initialization, filter application, and modal dismissal.
src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseService.java Changed return type of tasks in deleteTasksWithSolutionEntries from Set to List, affecting how tasks are managed internally.
src/main/webapp/i18n/de/programmingExercise.json Enhanced localization for feedback and filtering functionalities, adding keys for search, filter, and modal actions.
src/main/webapp/i18n/en/programmingExercise.json Similar enhancements for English localization, adding keys for feedback analysis and filtering options.
src/main/java/de/tum/cit/aet/artemis/assessment/dto/FeedbackPageableDTO.java Introduced FeedbackPageableDTO class for managing feedback-related data in a pageable format, including filtering criteria.
src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java Updated feedback retrieval methods to support pagination and filtering, introducing getFeedbackDetailsOnPage and getMaxCountForExercise methods.
src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java Renamed getAllFeedbackDetailsForExercise to getFeedbackDetailsPaged, updating its parameters and return type for improved feedback retrieval.
src/test/java/de/tum/cit/aet/artemis/assessment/ResultServiceIntegrationTest.java Updated integration tests to reflect changes in feedback retrieval methods, utilizing FeedbackAnalysisResponseDTO for assertions.
src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts Modified test suite for FeedbackAnalysisService to test new search and max count methods, updating mock data structures accordingly.
src/test/java/de/tum/cit/aet/artemis/programming/hestia/ProgrammingExerciseTaskIntegrationTest.java Changed type of extractedTasks from Set<ProgrammingExerciseTask> to List<ProgrammingExerciseTask> in the test method, affecting task order and access.

Possibly related PRs

Suggested labels

ready for review, enhancement

Suggested reviewers

  • JohannesStoehr
  • sarpsahinalp
  • eceeeren
  • MaximilianAnzinger
  • BBesrour

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

Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 0dc8573 and e7d16c7.

Files selected for processing (15)
  • src/main/java/de/tum/cit/aet/artemis/assessment/dto/FeedbackAnalysisResponseDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (4 hunks)
  • src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java (2 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.scss (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.scss (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (2 hunks)
  • src/main/webapp/i18n/de/programmingExercise.json (1 hunks)
  • src/main/webapp/i18n/en/programmingExercise.json (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/assessment/ResultServiceIntegrationTest.java (5 hunks)
  • src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (3 hunks)
Additional context used
Path-based instructions (12)
src/main/java/de/tum/cit/aet/artemis/assessment/dto/FeedbackAnalysisResponseDTO.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (1)

Pattern 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/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (1)

Pattern 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/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html (1)

Pattern 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/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (1)

Pattern 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/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/assessment/ResultServiceIntegrationTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/main/webapp/i18n/de/programmingExercise.json (1)

Pattern src/main/webapp/i18n/de/**/*.json: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

Biome
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts

[error] 20-22: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

GitHub Check: client-tests-selected
src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts

[failure] 38-38:
Argument of type '{ page: number; pageSize: number; searchTerm: string; sortingOrder: string; sortedColumn: string; }' is not assignable to parameter of type 'SearchTermPageableSearch'.

GitHub Check: client-tests
src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts

[failure] 38-38:
Argument of type '{ page: number; pageSize: number; searchTerm: string; sortingOrder: string; sortedColumn: string; }' is not assignable to parameter of type 'SearchTermPageableSearch'.

Additional comments not posted (60)
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.scss (3)

1-3: LGTM!

The .small-text class is implemented correctly and follows best practices:

  • The class name is semantic and describes its purpose.
  • The font size is specified in a relative unit (rem), which is a good practice for responsive design.

5-7: LGTM!

The .position-relative class is implemented correctly and follows best practices:

  • The class name is semantic and describes its purpose.
  • Setting the position to relative allows for absolute positioning of child elements without affecting the layout of surrounding elements.

9-13: LGTM!

The .search-icon class is implemented correctly and follows best practices:

  • The class name is semantic and describes its purpose.
  • Setting the position to absolute allows for precise placement of the icon within a relative container.
  • Setting pointer-events to none ensures that the icon does not interfere with mouse events, allowing clicks to pass through to underlying elements.
src/main/java/de/tum/cit/aet/artemis/assessment/dto/FeedbackAnalysisResponseDTO.java (1)

1-9: LGTM!

The FeedbackAnalysisResponseDTO class follows the best practices for defining DTOs:

  • It is a Java record, which is a concise way to define immutable data classes.
  • It has a single responsibility of representing the response of a feedback analysis operation.
  • It uses the @JsonInclude annotation to exclude empty fields from JSON serialization, which helps in reducing the payload size.
  • It follows the naming convention of using the DTO suffix for data transfer objects.
  • It is in the appropriate package for DTOs.
  • It does not have any methods, which is expected for a DTO.
  • It does not have any dependencies on entities, which is a good practice for DTOs.
  • It uses constructor injection, which is a recommended practice for dependency injection.

Great job!

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.scss (6)

1-3: LGTM!

The .modal-body class correctly adds padding to the modal body. The implementation follows best practices.


5-7: LGTM!

The .modal-label class correctly makes the text bold. The implementation follows best practices.


9-15: LGTM!

The .border class correctly adds a border and padding to an element. The implementation follows best practices.


17-21: LGTM!

The .modal-header class correctly removes the bottom border and adds padding to the modal header. The implementation follows best practices.


23-25: LGTM!

The .modal-body p class correctly removes the bottom margin from paragraphs inside the modal body. The implementation follows best practices.


27-29: LGTM!

The .modal-footer class correctly removes the top border from the modal footer. The implementation follows best practices.

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts (1)

6-17: LGTM!

The FeedbackModalComponent follows the Angular style guide and best practices:

  • The component is correctly defined using the Component decorator with the appropriate metadata.
  • The component is marked as standalone, which aligns with the Angular best practices for code reuse and modularity.
  • The component imports and uses the NgbActiveModal service to manage the modal's active state.
  • The component defines the input property feedbackDetail with the appropriate type.
  • The component constructor correctly injects the NgbActiveModal service.

The implementation looks good and adheres to the Angular coding standards.

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (2)

5-8: LGTM!

The new FeedbackAnalysisResponse interface provides a clear structure for the response from the feedback analysis service. Using SearchResult for feedbackDetails indicates that the results will be paginated, which is a good practice for handling large datasets. The totalItems property is also useful for displaying the total count of feedback details.


24-26: LGTM!

The new search method in the FeedbackAnalysisService class is well-designed and follows the best practices:

  • The method signature is clear and follows the naming conventions.
  • Using a POST request allows for more complex queries and better handling of large datasets compared to a GET request.
  • The method returns a promise of FeedbackAnalysisResponse, which provides a structured response format.

Great job!

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (2)

1-3: LGTM!

The modal header is well-structured and uses the jhiTranslate directive correctly for the title, following the localization best practices.


5-22: Great usage of flex layout and Angular directives!

The flex layout enhances the readability and visual separation of the feedback details. The jhiTranslate directive is used correctly for translating the labels, and the interpolation syntax is used correctly to display the dynamic feedback details.

src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (3)

3-3: LGTM!

The import statement is correct and necessary for using the FeedbackAnalysisResponse and FeedbackDetail interfaces in the test file.


14-17: LGTM!

The feedbackResponseMock object is correctly defined and matches the structure of FeedbackAnalysisResponse interface. It will be used to test the search method of the service.


38-45: LGTM!

The test case is correctly defined and tests the search method of the service. The expectations are correctly defined and match the feedbackResponseMock object.

Tools
GitHub Check: client-tests-selected

[failure] 38-38:
Argument of type '{ page: number; pageSize: number; searchTerm: string; sortingOrder: string; sortedColumn: string; }' is not assignable to parameter of type 'SearchTermPageableSearch'.

GitHub Check: client-tests

[failure] 38-38:
Argument of type '{ page: number; pageSize: number; searchTerm: string; sortingOrder: string; sortedColumn: string; }' is not assignable to parameter of type 'SearchTermPageableSearch'.

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (8)

1-8: LGTM!

The import statements are well-organized and follow the Angular style guide. They import the necessary modules and components required for the FeedbackAnalysisComponent.


13-16: LGTM!

The @Component decorator is correctly configured for the FeedbackAnalysisComponent. It follows the Angular style guide and sets the necessary properties for a standalone component. The imported module and provided service are appropriate for the component's functionality.


19-20: LGTM!

The input signals exerciseTitle and exerciseId are correctly declared using the InputSignal type and marked as required. This ensures that the component receives the necessary input data for its functionality. The naming of the input signals follows the camelCase convention, adhering to the Angular style guide.


22-30: LGTM!

The signals and computed property are correctly declared and initialized with appropriate default values. The naming of the signals and computed property follows the camelCase convention, adhering to the Angular style guide. The types of the signals are correctly specified, ensuring type safety. The collectionsSize computed property provides a convenient way to calculate the total number of items based on the current state of content and pageSize.


32-34: LGTM!

The injected services feedbackAnalysisService, alertService, and modalService are correctly declared as private properties using the inject function. This ensures that the services are properly injected and available for use within the component. The naming of the properties follows the camelCase convention, adhering to the Angular style guide.


36-41: LGTM!

The font awesome icon constants faSort, faSortUp, faSortDown, faMagnifyingGlass, and faMagnifyingGlassPlus are correctly declared as readonly properties. This ensures that their values cannot be modified after initialization. The naming of the icon constants follows the camelCase convention, adhering to the Angular style guide. Declaring the icon constants as readonly properties improves code readability and maintainability. The SortingOrder enum is also correctly declared as a readonly property.


43-47: LGTM!

The constructor correctly sets up an effect that calls the loadData method whenever the component's state changes. This ensures that the component's data is loaded and updated based on the current state of the signals. The effect is a clean and reactive way to handle data loading in the component.


67-90: LGTM!

The setPage, setSortedColumn, and search methods correctly update the respective signals based on the provided input and trigger the loadData method to fetch the updated data. This ensures that the component's state is properly updated and the data is refreshed when the pagination, sorting, or search parameters change.

The openFeedbackModal method appropriately opens the FeedbackModalComponent using the NgbModal service and passes the feedbackDetail to the modal instance. This allows the user to view the detailed feedback information in a modal dialog

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html (5)

1-12: Great use of ng-template and structural directives!

The introduction of the headerTemplate using ng-template and structural directives aligns with Angular best practices. It improves code modularity and reusability by creating a dynamic and reusable header structure.

The clickable headers with sorting icons enhance the user experience by allowing users to sort the table based on different columns.

Overall, the code segment is well-structured and follows Angular coding conventions.


15-15: Improved title accuracy.

Updating the title to use the exerciseTitle() function instead of directly accessing the variable ensures that the title always reflects the current exercise title accurately.

This change improves the reliability and correctness of the displayed title.


17-20: Enhanced interactivity with search functionality.

The addition of the search input field bound to the searchTerm variable and triggering the search function on input changes enhances the interactivity and usability of the component.

Users can now filter feedback in real-time based on their search terms, improving the overall user experience.

The code segment follows Angular best practices for two-way data binding and event handling.


25-42: Improved maintainability with reusable header template.

Modifying the table structure to utilize the headerTemplate for defining columns improves maintainability and readability by centralizing the header structure in a reusable template.

The use of the *ngTemplateOutlet directive allows for dynamic rendering of the header template with different context values, enabling flexibility in defining column-specific properties.

The code segment follows Angular best practices for template composition and reusability.


46-59: Improved data management and visual presentation.

Iterating the feedback details from content().resultsOnPage instead of feedbackDetails indicates a shift in how data is sourced for display, potentially improving data management and consistency.

Truncating long feedback detail texts to 100 characters, followed by an ellipsis, enhances the visual presentation and readability of the table while indicating the presence of additional content.

The code segment follows Angular best practices for data binding and conditional rendering.

src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (13)

6-9: LGTM!

The imports are necessary for the test suite and follow the best practices.


15-15: LGTM!

The variable declaration is necessary for the test suite and follows the best practices.


22-25: LGTM!

The constant declaration is necessary for the test suite and follows the best practices.


42-43: LGTM!

The spy setup is necessary for the test suite and follows the best practices.


44-45: LGTM!

The assignments are necessary for the test suite and follow the best practices.


47-47: LGTM!

The method call is necessary for the test suite and follows the best practices.


50-52: LGTM!

The afterEach block is necessary for the test suite and follows the best practices.


54-59: LGTM!

The test case is necessary for the test suite and follows the best practices.


63-80: LGTM!

The test cases are necessary for the test suite and follow the best practices.


83-91: LGTM!

The test case is necessary for the test suite and follows the best practices.


93-106: LGTM!

The test case is necessary for the test suite and follows the best practices.


108-117: LGTM!

The test case is necessary for the test suite and follows the best practices.


119-129: LGTM!

The test case is necessary for the test suite and follows the best practices.

src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java (3)

30-30: LGTM!

The import statement for FeedbackAnalysisResponseDTO is necessary and correctly added.


36-36: LGTM!

The import statement for SearchTermPageableSearchDTO is necessary and correctly added.


284-299: Excellent work on implementing the new endpoint!

The getFeedbackDetailsPaged endpoint follows the best practices and is implemented correctly:

  • It uses the appropriate HTTP method (POST) and URL (/exercises/{exerciseId}/feedback-details-paged).
  • It is properly annotated with @PostMapping and @EnforceAtLeastEditorInExercise to ensure that only users with editor role can access it.
  • It accepts exerciseId and SearchTermPageableSearchDTO as parameters to support pagination and filtering of feedback details.
  • It delegates the business logic to resultService.getFeedbackDetailsOnPage method, which is a good practice.
  • It returns an appropriate response type FeedbackAnalysisResponseDTO wrapped in a ResponseEntity.

Great job!

src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (2)

556-594: The method implementation looks good and aligns with the provided context.

The getFeedbackDetailsOnPage method correctly implements the requirements mentioned in the AI-generated summary. It supports pagination, filtering, and sorting of aggregated feedback details. The method also calculates relative counts and assigns task numbers based on the associated test case names.


556-594: The method changes are consistent with the provided list of alterations.

The list of alterations mentions that the method findAggregatedFeedbackByExerciseId has been modified and renamed to getFeedbackDetailsOnPage in the ResultService class. It also mentions the change in the method signature to accept a SearchTermPageableSearchDTO parameter.

The reviewed code confirms these changes. The method has been renamed and now accepts the SearchTermPageableSearchDTO parameter to support pagination, filtering, and sorting.

src/test/java/de/tum/cit/aet/artemis/assessment/ResultServiceIntegrationTest.java (8)

34-34: LGTM!

The import statement for FeedbackAnalysisResponseDTO is correct.


41-42: LGTM!

The import statements for SortingOrder and SearchTermPageableSearchDTO are correct.


746-750: LGTM!

The code correctly creates and configures a SearchTermPageableSearchDTO object for performing a paginated search with sorting. The chosen property values are reasonable for testing purposes.


752-762: LGTM!

The code correctly sends a POST request to the feedback details endpoint with the appropriate request body and expected response type. The assertions verify that the response contains the expected feedback details with the correct property values.


763-763: LGTM!

The assertion correctly verifies that the total number of feedback items in the response is 1, which is consistent with the test setup.


Line range hint 770-794: LGTM!

The code correctly sets up a test scenario with multiple student participations, results, and feedback objects. The feedback objects have different detail texts to test the handling of multiple unique feedback items. The setup is suitable for testing the feedback analysis functionality.


Line range hint 795-824: LGTM!

The code correctly configures the SearchTermPageableSearchDTO object for sorting and pagination. The assertions verify that the response contains the expected number of feedback details with the correct property values. The code properly handles the case of multiple unique feedback items and verifies their properties.


832-843: LGTM!

The code correctly configures the SearchTermPageableSearchDTO object for sorting and pagination. The assertions verify that the response contains no feedback details and the total number of items is 0 when there are no participations. The code properly handles the case when there are no participations and verifies the expected response.

src/main/webapp/i18n/en/programmingExercise.json (1)

334-338: LGTM!

The addition of the feedbackModal object with header and feedbackTitle properties enhances the user experience by providing clearer context and organization for error messages related to test case feedback. The property names and values use clear and concise language. This change aligns well with the motivation to improve the quality of feedback given to students.

src/main/webapp/i18n/de/programmingExercise.json (2)

332-332: LGTM!

The German translation for the error message is accurate.


333-336: Sieht gut aus!

Die deutschen Übersetzungen für den Feedback-Modal sind korrekt und verwenden wie gefordert informelles Deutsch. Die Änderungen stimmen mit der KI-generierten Zusammenfassung überein.

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 14, 2024
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: 2

Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between e7d16c7 and f03def0.

Files selected for processing (8)
  • src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (4 hunks)
  • src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java (2 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (2 hunks)
  • src/main/webapp/i18n/de/programmingExercise.json (1 hunks)
  • src/main/webapp/i18n/en/programmingExercise.json (1 hunks)
  • src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (3 hunks)
Additional context used
Path-based instructions (7)
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (1)

Pattern 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/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (1)

Pattern 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/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (1)

Pattern 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/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/webapp/i18n/de/programmingExercise.json (1)

Pattern src/main/webapp/i18n/de/**/*.json: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

Biome
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts

[error] 20-22: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

Additional comments not posted (27)
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (4)

5-8: LGTM!

The new FeedbackAnalysisResponse interface provides a clear structure for the response returned by the service. It improves the clarity and organization of the data. The interface name and property names follow the naming conventions.


24-25: LGTM!

The new search method in the FeedbackAnalysisService class allows for better handling of large datasets and potentially more intricate search criteria. The method name and parameter names follow the naming conventions. The method returns a promise of type FeedbackAnalysisResponse, which is the new interface defined earlier.


2-2: LGTM!

The import statement for SearchResult and SearchTermPageableSearch is necessary for using these types in the file.


20-22: Remove the unnecessary constructor.

The constructor in the FeedbackAnalysisService class is unnecessary as it only calls the superclass constructor without any additional logic. Please remove the constructor to simplify the code.

Apply this diff to remove the constructor:

@Injectable()
export class FeedbackAnalysisService extends BaseApiHttpService {
-    constructor() {
-        super();
-    }
 
     search(pageable: SearchTermPageableSearch, options: { exerciseId: number }): Promise<FeedbackAnalysisResponse> {
         return this.post<FeedbackAnalysisResponse>(`exercises/${options.exerciseId}/feedback-details-paged`, pageable);
     }
}
Tools
Biome

[error] 20-22: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (3)

1-34: LGTM!

The modal dialog is well-structured and follows best practices. The use of jhiTranslate directive for localization is consistent with the rest of the application.


28-33: Translate the button text.

To maintain consistency with the rest of the modal and follow the localization best practices, consider translating the button text using the jhiTranslate directive.

-    <button
-        type="button"
-        class="btn btn-outline-primary"
-        jhiTranslate="artemisApp.programmingExercise.configureGrading.feedbackAnalysis.feedbackModal.ok"
-        (click)="activeModal.close('Close click')"
-    ></button>
+    <button
+        type="button"
+        class="btn btn-outline-primary"
+        (click)="activeModal.close('Close click')"
+        jhiTranslate="artemisApp.programmingExercise.configureGrading.feedbackAnalysis.feedbackModal.closeButton"
+    ></button>

20-20: Consider using a dynamic value for the error category.

If the error category information is available in the feedbackDetail object, consider using a dynamic value instead of hardcoding it as "Student Error".

-            <p>Student Error</p>
+            <p>{{ feedbackDetail.errorCategory }}</p>
src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (3)

3-4: LGTM!

The import changes are consistent with the list of alterations and are necessary for the updated test suite.


15-19: LGTM!

The feedbackResponseMock object is consistent with the list of alterations and is necessary for testing the updated search method.


34-54: LGTM!

The search test case accurately tests the updated search method with the following changes:

  • Uses a SearchTermPageableSearch object for the pageable parameter.
  • Uses a POST request instead of a GET request.
  • Expects a FeedbackAnalysisResponse object in the response.

The test case is consistent with the list of alterations and correctly asserts the response.

src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (13)

6-9: LGTM!

The imports are correctly added and necessary for the test suite.


15-15: LGTM!

The spy variable is correctly declared for mocking the service method in the tests.


22-25: LGTM!

The mock response object is correctly defined for simulating the service response in the tests.


41-41: LGTM!

The spy is correctly set up and the mock return value is correctly assigned for the search method of FeedbackAnalysisService.


43-44: LGTM!

The exerciseId and exerciseTitle properties are correctly set using Angular's signal for reactive state management.


46-46: LGTM!

Triggering change detection is necessary to ensure the component updates correctly after setting the properties.


49-51: LGTM!

Restoring mocks after each test is a good practice to ensure test isolation and avoid side effects.


53-59: LGTM!

The test case correctly verifies that the service method is called, and the component state is updated with the mock data on initialization.


62-79: LGTM!

The test cases correctly verify the behavior of the loadData method in both success and error scenarios, ensuring that the component state is updated correctly and errors are handled.


82-90: LGTM!

The test case correctly verifies the behavior of the setPage method, ensuring that the page is updated and the data is reloaded.


92-105: LGTM!

The test case correctly verifies the behavior of the setSortedColumn method, ensuring that the sortedColumn and sortingOrder properties are updated correctly and the data is reloaded.


107-116: LGTM!

The test case correctly verifies the behavior of the search method, ensuring that the page is reset and the data is loaded when searching.


118-128: LGTM!

The test case correctly verifies the behavior of the openFeedbackModal method, ensuring that the modal is opened with the correct feedback detail.

src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java (1)

284-299: LGTM!

The getFeedbackDetailsPaged function is well-designed and follows best practices:

  • The function signature and Javadoc provide clear information about the purpose, parameters, and return type of the function.
  • The function delegates the actual retrieval of feedback details to the service layer, keeping the controller layer thin.
  • The function adheres to the REST API design principles by using appropriate HTTP methods and response codes.
  • The function uses constructor injection for dependency injection.
  • The function uses the @EnforceAtLeastEditorInExercise annotation for authorization checks.
src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (1)

556-571: The getFeedbackDetailsOnPage method implementation looks good!

The method correctly retrieves paginated and filtered aggregated feedback details for a given exercise, with support for searching, sorting, and pagination. The code is well-structured and follows the specified requirements.

src/main/webapp/i18n/en/programmingExercise.json (1)

334-339: LGTM!

The addition of the feedbackModal object enhances the structure and organization of error messages related to test case feedback. It provides clearer context and improves the user experience when encountering errors while loading feedback.

src/main/webapp/i18n/de/programmingExercise.json (1)

333-337: Die Übersetzungen für das Feedback-Modal sehen gut aus!

Die hinzugefügten Übersetzungen für Header, Titel und OK-Button des neuen Feedback-Modals sind angemessen formuliert, verwenden die informelle Ansprache und fügen sich gut in den bestehenden Übersetzungs-JSON ein.

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 14, 2024
Copy link
Contributor

@pzdr7 pzdr7 left a comment

Choose a reason for hiding this comment

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

Some comments on the code - I cannot say too much about the pagination, though

…factor-and-add-filtering-for-erroranalysis' into feature/programming-exercises/refactor-and-add-filtering-for-erroranalysis
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

Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between f03def0 and e6f41e1.

Files selected for processing (8)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (1 hunks)
  • src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (2 hunks)
  • src/main/webapp/i18n/de/programmingExercise.json (1 hunks)
  • src/main/webapp/i18n/en/programmingExercise.json (1 hunks)
  • src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (2 hunks)
Additional context used
Path-based instructions (7)
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html (1)

Pattern 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/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (1)

Pattern 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/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (1)

Pattern 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/main/webapp/i18n/de/programmingExercise.json (1)

Pattern src/main/webapp/i18n/de/**/*.json: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

Additional comments not posted (32)
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.ts (2)

1-5: LGTM!

The import statements are correctly used, follow the Angular style guide, and adhere to the project's directory structure. The imports are also alphabetically ordered and the line lengths are within the acceptable limit.


6-12: LGTM!

The component decorator is correctly used and follows the Angular style guide. The component selector prefix jhi is consistently used across the project. The component template and styles are linked using relative paths, which is a good practice. The component imports ArtemisSharedCommonModule, which is likely a shared module containing common dependencies. The component is also marked as standalone, which aligns with the Angular's standalone components feature.

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (3)

5-8: LGTM!

The FeedbackAnalysisResponse interface provides a clear and structured format for the response returned by the feedback analysis service. The use of SearchResult<FeedbackDetail> for the feedbackDetails property indicates that the response will include paginated results, and the totalItems property is useful for handling pagination. This interface improves the clarity and organization of the data returned by the service.


20-21: LGTM!

The search method in the FeedbackAnalysisService class is a significant improvement over the previous getFeedbackDetailsForExercise method. It allows for more complex querying and handling of large datasets through pagination by accepting a SearchTermPageableSearch object and an options object containing exerciseId. The method performs a POST request to fetch paginated feedback details for a specific exercise and returns a promise of type FeedbackAnalysisResponse, which provides a structured format for the response data. The method name accurately describes its functionality.


20-22: Remove the unnecessary constructor.

The constructor in the FeedbackAnalysisService class is unnecessary as it only calls the superclass constructor without any additional logic. Please remove the constructor to simplify the code.

Apply this diff to remove the constructor:

@Injectable({ providedIn: 'root' })
export class FeedbackAnalysisService extends BaseApiHttpService {
-    constructor() {
-        super();
-    }
 
     search(pageable: SearchTermPageableSearch, options: { exerciseId: number }): Promise<FeedbackAnalysisResponse> {
         return this.post<FeedbackAnalysisResponse>(`exercises/${options.exerciseId}/feedback-details-paged`, pageable);
     }
}
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/Modal/feedback-modal.component.html (2)

1-34: LGTM! The modal structure and translations are well-implemented.

The modal follows the standard header, body, and footer layout, and the translations are correctly used for the header, labels, and button text. The feedback details are displayed using appropriate bindings to the feedbackDetail object.


20-20: Consider using a dynamic value for the error category.

If the error category information is available in the feedbackDetail object, consider using a dynamic value instead of hardcoding it as "Student Error".

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html (4)

1-8: LGTM!

The new headerTemplate is a great addition for creating a modular and reusable structure for table headers. It effectively leverages Angular's structural directives and allows for dynamic sorting capabilities, enhancing the user experience.


11-11: LGTM!

Updating the title to utilize the exerciseTitle() function is a great change. It ensures that the displayed title always reflects the most current exercise title, enhancing the accuracy and dynamism of the interface.


13-23: Address the localization of the placeholder text.

The addition of the search input field is a great feature for improving the component's interactivity and usability. Binding the input to the searchTerm variable and triggering a search function on changes is the correct approach.

However, as mentioned in a previous review comment, the placeholder text should be localized using artemisTranslate for a better user experience.


28-45: LGTM!

Revising the table structure to use the new headerTemplate for defining columns is an excellent change. It enhances the maintainability and readability of the code. The *ngTemplateOutlet directive is used correctly to apply the template to each column header, resulting in a more organized and readable structure.

src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (6)

1-8: LGTM!

The import statements are well-structured, follow the Angular style guide, and include all the necessary dependencies for the component's functionality. The import paths are correct and point to the expected locations.


13-16: Component metadata looks good!

The component is correctly configured as a standalone component, which aligns with Angular's best practices. The ArtemisSharedCommonModule is imported, promoting code reuse. The FeedbackAnalysisService is provided, ensuring that the component has access to the necessary service for fetching feedback details.


19-20: Input properties are well-defined!

The use of InputSignal for exerciseTitle and exerciseId aligns with Angular's reactive programming paradigm. The input.required ensures that the component receives the necessary data. The types of the input properties are correctly specified as string and number, providing type safety.


22-30: Signals and computed property are effectively used!

The use of signals for managing the component's state, such as pagination, sorting, and search term, aligns with Angular's reactive programming principles. The naming of the signals is clear and descriptive, making the code more readable. The computed property collectionsSize is correctly derived from content and pageSize, ensuring that it stays up to date with any changes in the dependent signals.


45-50: Constructor and effect are properly implemented!

The use of effect in the constructor aligns with Angular's reactive programming principles for handling side effects. The effect is triggered whenever the component's state changes, ensuring that the data is always up to date. Calling the loadData method within the effect is a good practice for fetching the feedback details based on the current state.


69-92: Methods for pagination, sorting, and opening the feedback modal are implemented correctly!

The setPage, setSortedColumn, and search methods correctly update the respective signals based on the user's actions. Triggering the loadData method after updating the signals ensures that the data is fetched with the updated state, keeping the component's data in sync with the user's actions.

The openFeedbackModal method properly opens the FeedbackModalComponent with the selected feedbackDetail, allowing users to view the detailed feedback information in a modal.

Overall, these methods enhance the user experience by providing pagination, sorting, and detailed feedback viewing capabilities.

src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.component.spec.ts (12)

6-8: LGTM!

The additional imports are necessary for the updated test suite and look good.


14-14: LGTM!

The searchSpy variable declaration looks good and is used appropriately in the test suite.


21-25: LGTM!

The feedbackResponseMock constant declaration looks good and is used appropriately in the test suite.


40-41: LGTM!

The searchSpy setup looks good and is used appropriately in the test suite.


42-44: LGTM!

Setting the exerciseId and exerciseTitle inputs looks good and is necessary for the updated test suite.


48-50: LGTM!

Restoring mocks in the afterEach block is a good practice and looks good.


52-59: LGTM!

The test case for component initialization looks good and covers the necessary scenarios.


61-79: LGTM!

The test cases for the loadData method look good and cover the necessary scenarios, including the error handling scenario.


81-89: LGTM!

The test case for the setPage method looks good and covers the necessary scenario.


91-104: LGTM!

The test case for the setSortedColumn method looks good and covers the necessary scenarios, including the toggling of the sortingOrder.


106-115: LGTM!

The test case for the search method looks good and covers the necessary scenario.


117-127: LGTM!

The test case for the openFeedbackModal method looks good and covers the necessary scenario.

src/main/webapp/i18n/en/programmingExercise.json (2)

335-335: LGTM!

The search key with the value "Search ..." looks good for a search placeholder.


336-340: The new feedbackModal object looks good!

The header, feedbackTitle and ok keys provide a clear structure for displaying error details about test case feedback in a modal. The chosen values are appropriate.

src/main/webapp/i18n/de/programmingExercise.json (1)

332-338: LGTM!

The newly added translation keys for the feedback analysis modal are clear and consistent:

  • feedbackModal.header correctly translates to "Fehler Details" (Error Details).
  • feedbackModal.feedbackTitle correctly translates to "Testfall Feedback" (Test Case Feedback).
  • feedbackModal.ok is simply labeled "Ok".

The informal tone (dutzen) is used appropriately. The translations adhere to the existing conventions in the file.

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: 2

🧹 Outside diff range and nitpick comments (2)
src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (2)

545-570: Enhance method documentation for better clarity.

The Javadoc is well-structured but could be improved in the following areas:

  1. Add @throws documentation for potential exceptions (NumberFormatException, BadRequestAlertException).
  2. Clarify that task filtering is done by task numbers, not task names as currently documented.
     /**
      * Retrieves paginated and filtered aggregated feedback details for a given exercise.
      * <br>
      * For each feedback detail:
      * 1. The relative count is calculated as a percentage of the total number of distinct results for the exercise.
      * 2. The task numbers are assigned based on the associated test case names. A mapping between test cases and tasks is created using the set of tasks retrieved from the
      * database.
      * <br>
      * Filtering:
      * - **Search term**: Filters feedback details by the search term (case-insensitive).
      * - **Test case names**: Filters feedback based on specific test case names (if provided).
-     * - **Task names**: Maps provided task numbers to task names and filters feedback based on the test cases associated with those tasks.
+     * - **Task numbers**: Maps provided task numbers (1-based indices) to task names and filters feedback based on the test cases associated with those tasks.
      * - **Occurrences**: Filters feedback where the number of occurrences (COUNT) is between the provided minimum and maximum values (inclusive).
      * <br>
      * Pagination and sorting:
      * - Sorting is applied based on the specified column and order (ascending or descending).
      * - The result is paginated based on the provided page number and page size.
      *
      * @param exerciseId The ID of the exercise for which feedback details should be retrieved.
      * @param data       The {@link FeedbackPageableDTO} containing page number, page size, search term, sorting options, and filtering parameters (task names, test cases,
      *                       occurrence range).
+     * @throws NumberFormatException if the provided task numbers or occurrence range values are not valid numbers
+     * @throws BadRequestAlertException if the exercise is not found
      * @return A {@link FeedbackAnalysisResponseDTO} object containing:
      *         - A {@link SearchResultPageDTO} of paginated feedback details.
      *         - The total number of distinct results for the exercise.
      *         - The total number of tasks associated with the feedback.
      *         - A list of test case names included in the feedback.
      */

571-612: Consider splitting the feedback analysis logic into a separate service.

The getFeedbackDetailsOnPage method handles complex feedback analysis logic that could be better managed in a dedicated service. This would improve maintainability and follow the Single Responsibility Principle more closely.

Consider creating a new FeedbackAnalysisService that would:

  1. Handle all feedback analysis-related operations
  2. Encapsulate the filtering, mapping, and processing logic
  3. Make the code more testable and maintainable

Example structure:

@Service
public class FeedbackAnalysisService {
    private final StudentParticipationRepository studentParticipationRepository;
    private final ProgrammingExerciseRepository programmingExerciseRepository;
    private final ProgrammingExerciseTaskService programmingExerciseTaskService;

    // Move the feedback analysis methods here
    public FeedbackAnalysisResponseDTO getFeedbackDetailsOnPage(long exerciseId, FeedbackPageableDTO data) {
        // Current implementation
    }

    public long getMaxCountForExercise(long exerciseId) {
        // Current implementation
    }

    // Extract helper methods
    private List<String> generateFilterTaskNames(List<String> taskIndices, List<ProgrammingExerciseTask> tasks) {
        // Task filtering logic
    }

    private List<FeedbackDetailDTO> processFeedbackDetails(Page<FeedbackDetailDTO> page, List<ProgrammingExerciseTask> tasks, long distinctResultCount) {
        // Feedback processing logic
    }
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6e20397 and c9182c8.

📒 Files selected for processing (1)
  • src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 22, 2024
Copy link
Contributor

@JohannesWt JohannesWt left a comment

Choose a reason for hiding this comment

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

Reapprove after merge conflict

Copy link

@Malekos74 Malekos74 left a comment

Choose a reason for hiding this comment

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

Reapprove merge conflict

Copy link

@zagemello zagemello left a comment

Choose a reason for hiding this comment

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

Tested and all features work as intended.

@az108 az108 requested a review from zagemello October 23, 2024 20:44
Copy link

@Cathy0123456789 Cathy0123456789 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 TS1. Works great! Also symbols don't cause any problems while filtering, however ä, ö or ü don't work as expected, it seems to interpret the alphabets as a, o and u instead

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 client Pull requests that update TypeScript code. (Added Automatically!) core Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module ready to merge server Pull requests that update Java code. (Added Automatically!) tests
Projects
Archived in project
Status: Done
Development

Successfully merging this pull request may close these issues.