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: Refactor course sidebar into its own component #10455

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

Conversation

tobias-lippert
Copy link
Contributor

@tobias-lippert tobias-lippert commented Mar 8, 2025

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 (e.g. using paging).
  • 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 documented the TypeScript code using JSDoc style.

Motivation and Context

We want to introduce the sidebar layout in the course management view with the next major release.
As first step make the sidebar in the student course view its own component to be able to reuse it in the management view

Description

Created a new component course-sidebar and adjusted course-overview to use the new course-sidebar.

Steps for Testing

Prerequisites:

  • 1 Student
  1. Log in to Artemis
  2. Navigate to any course
  3. Try out the sidebar, make sure nothing breaks and behaves differently to before
  4. When the space is not sufficient to display all items, a more menu should be shown. This should open with the hidden items when you click on it
  5. When clicking on the course icon, a list of courses should be shown

Exam Mode Testing

Prerequisites:

  • 1 Student
  1. Log in to Artemis
  2. Participate in the exam as a student
  3. Make sure the sidebar is not shown in exam mode

Testserver States

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

Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Exam Mode Test

  • Test 1
  • Test 2

Test Coverage

Class/File Line Coverage Confirmation (assert/expect)
course-sidebar.component 97%
course-overview.component 88% ✅ 3% higher than before

Summary by CodeRabbit

  • New Features
    • Introduced new input properties for the course sidebar component to enhance data handling.
    • Added a collapsible design for the course sidebar, improving user navigation experience.
  • Refactor
    • Simplified event handling in various components by renaming output events for clarity.
    • Organized sidebar item generation logic within dedicated methods to improve maintainability.
  • Style
    • Updated sidebar styling with new classes and improved visual feedback for user interactions.
  • Tests
    • Expanded test coverage for the course overview and sidebar components to validate new functionalities.

@github-actions github-actions bot added tests client Pull requests that update TypeScript code. (Added Automatically!) labels Mar 8, 2025
@tobias-lippert tobias-lippert marked this pull request as ready for review March 9, 2025 09:43
@tobias-lippert tobias-lippert requested a review from a team as a code owner March 9, 2025 09:43
Copy link

coderabbitai bot commented Mar 9, 2025

Walkthrough

The pull request introduces significant modifications to the course overview and sidebar components. It adds new input properties to the <jhi-course-sidebar> component, removes the atlasEnabled property, and restructures the sidebar's styling and functionality. The component logic has been enhanced with new methods for generating sidebar and action items, while several CSS classes have been removed or added to improve the visual feedback and responsiveness of the sidebar. Additionally, event bindings have been updated to reflect new naming conventions.

Changes

File(s) Change Summary
src/main/webapp/app/overview/course-overview.component.html, src/main/webapp/app/overview/course-overview.component.ts Added input properties sidebarItems and courseActionItems to <jhi-course-sidebar>, removed atlasEnabled, and introduced new methods for generating sidebar items and course actions.
src/main/webapp/app/overview/course-overview.component.scss Removed multiple CSS classes related to the sidebar, added styles for .btn-sidebar-collapse, and updated media queries for print styles.
src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html, src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts, src/main/webapp/app/overview/course-sidebar/course-sidebar.component.scss Introduced a new sidebar component with dynamic rendering, collapsible functionality, and comprehensive styling.
src/test/javascript/spec/component/course/course-overview.component.spec.ts Updated tests to include new properties and methods for sidebar items and action items, enhancing test coverage for the CourseOverviewComponent.
src/test/javascript/spec/component/course/course-sidebar.component.spec.ts Simplified tests by removing checks for input changes and focusing on the initialization of visible items and event emissions.
src/main/webapp/app/exam/manage/students/exam-students.component.html, src/main/webapp/app/exam/manage/students/upload-images/students-upload-images-button.component.ts, src/main/webapp/app/shared/user-import/users-import-button.component.ts Updated event bindings from (finish) to (importDone) and (uploadDone) for better clarity in event handling.
src/main/webapp/app/shared/markdown-editor/monaco/markdown-editor-monaco.component.ts Added a new input property isInCommunication to track the communication state in the Markdown editor component.
src/main/webapp/app/shared/util/markdown.conversion.util.ts Enhanced Markdown processing capabilities by introducing new functions for token class assignment and updating the initialization of the Markdown parser.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Overview
    participant Sidebar

    User->>Overview: Load course overview
    Overview->>Sidebar: Provide course data and state flags
    User->>Sidebar: Toggle collapse / select course action
    Sidebar-->>Overview: Emit event (switchCourse, courseActionItemClick, toggleCollapseState)
    Note over Sidebar: Internal state updated on window resize
Loading

Possibly related PRs

  • General: Allow to switch courses from the course icon #8669: The changes in the main PR, which involve adding new input properties to the <jhi-course-sidebar> component and modifying its functionality, are related to the retrieved PR that introduces a new dropdown for switching courses and modifies the course overview component, as both involve enhancements to course navigation and sidebar functionality.
  • Communication: Add recents section to sidebar #10033: The changes in the main PR, which involve adding new input properties to the <jhi-course-sidebar> component and modifying the sidebar's functionality, are related to the retrieved PR that introduces a new "Recents" section in the sidebar, as both PRs focus on enhancing the sidebar component's capabilities and structure.
  • Development: Fix console errors on course overview page #9526: The changes in the main PR, which involve adding and removing input properties in the course-overview.component.html, are related to the modifications in the retrieved PR that also address null-safe checks in the same component's HTML, ensuring robust handling of potentially undefined properties.

Suggested labels

ready to merge, component:Communication, small

Suggested reviewers

  • florian-glombik
  • JohannesStoehr
  • rabeatwork
  • az108
  • coolchock
  • HawKhiem
  • SimonEntholzer
  • krusche
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
  • @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: 0

🔭 Outside diff range comments (1)
src/main/webapp/app/overview/course-overview.component.scss (1)

1-262: ⚠️ Potential issue

Fix code duplication in SCSS file

The file contains significant duplication with almost identical code appearing twice (first between lines 1-262 and then again from lines 263-524). This duplication should be removed to improve maintainability.

Remove the duplicated code by keeping only one copy of each CSS rule.

Also applies to: 263-524

🧹 Nitpick comments (5)
src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (1)

77-101: Consider potential memory leak with window resize listener.

The window resize event listener is properly implemented with HostListener. However, to ensure there are no memory leaks, consider adding cleanup in the OnDestroy lifecycle hook.

-export class CourseSidebarComponent implements OnInit, OnChanges {
+export class CourseSidebarComponent implements OnInit, OnChanges, OnDestroy {
     // ... existing code ...

+    ngOnDestroy() {
+        // Clean up logic if needed
+    }
}
src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html (2)

101-111: Great keyboard accessibility for the collapse control!

The collapse chevron includes a keyboard shortcut (Ctrl + M) in the tooltip, which enhances accessibility. Consider adding ARIA attributes for screen readers.

 <div
     class="double-arrow mb-2"
     [ngClass]="{ 'menu-closed': isNavbarCollapsed }"
     [ngbTooltip]="(isNavbarCollapsed ? 'Expand' : 'Collapse') + ' Menu (Ctrl + M)'"
     (click)="toggleCollapseState.emit()"
+    role="button"
+    tabindex="0"
+    aria-label="Toggle sidebar menu"
 >

169-178: Consider simplifying conditional CSS classes

The ngClass object could become complex to maintain. Consider extracting this logic to a method in the component class for better readability and testability.

 [ngClass]="{
     'guided-tour': sidebarItem.guidedTour,
-    newMessage: !communicationRouteLoaded && hasUnreadMessages && sidebarItem.title === 'Communication',
+    newMessage: hasNewCommunicationMessage(sidebarItem),
     collapsed: isNavbarCollapsed,
 }"

Then in your component:

hasNewCommunicationMessage(item: SidebarItem): boolean {
  return !this.communicationRouteLoaded && this.hasUnreadMessages && item.title === 'Communication';
}
src/main/webapp/app/overview/course-overview.component.html (1)

36-37: Minor spacing inconsistency

There's an extra blank line after the sidebar component that could be removed for more consistent spacing with the rest of the file.

            <mat-sidenav
                disableClose
                [ngClass]="{ 'sidenav-height-dev': !isProduction || isTestServer }"
                class="module-bg rounded-3"
                opened="true"
                mode="side"
                [hidden]="isExamStarted"
            >
                <jhi-course-sidebar
                    [course]="course"
                    [courses]="courses"
                    [sidebarItems]="sidebarItems"
                    [courseActionItems]="courseActionItems"
                    [isNavbarCollapsed]="isNavbarCollapsed"
                    [isExamStarted]="isExamStarted"
                    [isProduction]="isProduction"
                    [isTestServer]="isTestServer"
                    [hasUnreadMessages]="hasUnreadMessages"
                    [communicationRouteLoaded]="communicationRouteLoaded"
                    (switchCourse)="switchCourse($event)"
                    (courseActionItemClick)="courseActionItemClick($event)"
                    (toggleCollapseState)="toggleCollapseState()"
                />
-
            </mat-sidenav>
src/main/webapp/app/overview/course-overview.component.ts (1)

219-220: Type annotation improvement opportunity

The subscription handler lacks proper type annotations for the params object. Consider adding a stronger type to improve type safety.

-        this.subscription = this.route.params.subscribe((params: { courseId: string }) => {
+        this.subscription = this.route.params.subscribe((params: { courseId: string; [key: string]: string }) => {
            this.courseId = Number(params.courseId);
        });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 675d958 and 811f313.

📒 Files selected for processing (8)
  • src/main/webapp/app/overview/course-overview.component.html (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.scss (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (7 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html (1 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.scss (1 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (1 hunks)
  • src/test/javascript/spec/component/course/course-overview.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
`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/course/course-overview.component.spec.ts
  • src/test/javascript/spec/component/course/course-sidebar.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/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-overview.component.ts
`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/overview/course-overview.component.html
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Call Build Workflow / Build and Push Docker Image
  • GitHub Check: Call Build Workflow / Build .war artifact
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Analyse
🔇 Additional comments (33)
src/test/javascript/spec/component/course/course-overview.component.spec.ts (2)

62-62: LGTM! Import for the new sidebar component.

The import for CourseSidebarComponent correctly follows the project's import structure.


187-187: LGTM! Proper mocking of the new sidebar component.

The course sidebar component is properly mocked in the test setup using NgMocks, which follows the project's testing guidelines.

src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (6)

1-23: LGTM! Well-structured test imports and dependencies.

The imports are properly organized and include all necessary components, directives, and services for testing. The mock services and test utilities are appropriately imported.


24-92: LGTM! Comprehensive test setup with well-defined mock data.

The test data setup is thorough and includes mock courses, sidebar items, and action items with all necessary properties. The various sidebar item configurations test different use cases including feature toggles, Orion window behavior, and guidedTour support.


93-143: LGTM! Well-configured TestBed setup.

The TestBed configuration properly includes all necessary imports, components, and providers. The component instance is initialized with appropriate test data. The setup includes all required Angular testing modules and proper mocking of external dependencies.


145-217: LGTM! Thorough tests for visibility and threshold calculations.

The tests effectively verify the component's core functionality for calculating visibility thresholds and updating visible navbar items. Tests cover initialization, changes to inputs, window resize events, and dropdown behavior.


219-254: LGTM! Good coverage of display logic tests.

The tests properly verify the display logic for course titles, icons, and dropdown visibility based on component state.


256-283: LGTM! Comprehensive event emission tests.

The tests efficiently verify that the component correctly emits events for user interactions, including toggling collapse state, switching courses, and clicking action items.

src/main/webapp/app/overview/course-sidebar/course-sidebar.component.scss (5)

1-21: LGTM! Well-structured SCSS with proper variable definitions.

The import structure follows best practices by including Bootstrap functions, variables, and mixins. The custom variables for menu widths and transition durations are well-defined and enhance maintainability.


23-46: LGTM! Clean implementation of message notification styles.

Using a placeholder selector (%message-block) for the notification styles is a good practice for code reuse. The styles are appropriately applied to both normal and collapsed menu states.


48-77: LGTM! Smooth transition effects for menu controls.

The transition effects for the double arrow and icon rotation provide good visual feedback for users. The transform and transition properties are well-utilized for creating the animation effects.


79-131: LGTM! Good responsive design implementation.

The styles properly handle different screen sizes with appropriate media queries. The course circle and title styles maintain consistent visual appearance across different states.


133-167: LGTM! Well-structured dropdown styles with print considerations.

The dropdown menu styles are comprehensive and maintain consistent appearance. The print media query appropriately hides the sidebar when printing, which is a good user experience consideration.

src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (5)

1-13: LGTM! Proper import structure following Angular guidelines.

The imports are organized correctly, with Angular core imports followed by application-specific imports. All necessary components, directives, and services are properly imported.


14-32: LGTM! Well-defined interfaces for component types.

The CourseActionItem and SidebarItem interfaces are well-structured and provide clear type definitions for the component's data models. Using interfaces enhances code readability and type safety.


34-56: LGTM! Proper component configuration using standalone components.

The component is properly configured as a standalone component with all necessary imports. The selector, template, and stylesheet paths follow Angular naming conventions.


57-76: LGTM! Well-structured component with proper input/output properties.

The component has clearly defined input and output properties. The state management for hidden items is properly encapsulated within the component.


102-134: LGTM! Well-implemented sidebar visibility logic.

The methods for calculating thresholds and determining visible items are well-structured and properly commented. The reverse order approach for hiding items from the bottom is a good implementation detail.

src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html (4)

1-113: Good implementation of the sidebar container structure!

The sidebar layout is well-organized with a clean flex structure that separates the component into logical sections (course header, navigation items, and action items). The collapsed state is properly managed through the isNavbarCollapsed property and consistently applied with ngClass.


7-15: Effective use of the new Angular control flow syntax!

Great job using the modern @if and @for syntax instead of the deprecated *ngIf and *ngFor directives, which aligns with the provided coding guidelines.


43-77: Well-implemented overflow handling for navigation items!

The implementation of hidden items with a dropdown menu ensures good UX when there are too many navigation items. The three-dots menu provides a clean way to access overflow items.


115-182: Excellent use of templates for code reusability!

Breaking out the common UI patterns into ng-templates promotes reusability and maintainability. The templates for course images and navigation items are well-structured and consistently applied throughout the component.

src/main/webapp/app/overview/course-overview.component.scss (4)

240-252: Good implementation of print styles!

The print-specific media query that hides the sidebar when printing is a thoughtful addition that improves the user experience for printed content.


156-171: Well-structured button hover and focus states

The hover and focus states for the sidebar collapse button provide good visual feedback to users. The transitions are smooth and enhance the user experience.


9-14: Good use of CSS variables for transitions

Defining transition timing variables at the top of the file promotes consistency and makes it easier to fine-tune animations throughout the component.


254-262: Responsive handling for small screens

The media query for small screens appropriately adjusts the chevron rotation direction for the communication module, ensuring consistent behavior across device sizes.

src/main/webapp/app/overview/course-overview.component.html (2)

21-35: Excellent component refactoring!

The replacement of complex sidebar markup with a single <jhi-course-sidebar> component significantly improves code readability and maintainability. The input and output bindings are well-organized and follow Angular best practices.


1-131: Good use of modern Angular control flow syntax

The template uses the new Angular control flow syntax with @if and @for instead of the older *ngIf and *ngFor directives, which aligns with the provided coding guidelines.

src/main/webapp/app/overview/course-overview.component.ts (5)

16-24: Well-organized imports

The imports have been properly reorganized and grouped by type (Angular core, HTTP, RxJS, etc.), making the code more maintainable.


81-81: Good component modularity with interface imports

Importing the interfaces from the new sidebar component (instead of duplicating them) follows the DRY principle and establishes a single source of truth for these types.


83-103: Proper use of standalone component feature

Adding standalone: true and explicitly importing all the required dependencies helps with tree-shaking and follows Angular's modern architecture practices.


715-719: Good documentation in ngOnDestroy method

The added comments in the ngOnDestroy method improve code readability by clarifying the purpose of cleanup operations.


732-738: Comprehensive unsubscribe handling

The ngOnDestroy method properly unsubscribes from all subscriptions, including the new sidebar-related ones, which effectively prevents memory leaks.

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 9, 2025
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: 0

🧹 Nitpick comments (3)
src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html (3)

44-51: Consider usability for many hidden items.
When hiddenItems().length grows large, the layout applies a fixed content size. Consider adding auto-scroll or pagination for a better user experience.


115-125: Add alt text for accessibility.
The <jhi-secured-image> displays a course icon but lacks an alt attribute. Consider dynamically setting a descriptive alt (e.g., the course title) to improve screen reader support.

- <jhi-secured-image [src]="courseImage"/>
+ <jhi-secured-image [src]="courseImage" alt="{{ courseTitle }}"/>

137-142: Check for code duplication in nav templates.
navIconAndText and navIconAndTextHidden are nearly identical except for the collapsed text handling. Consider consolidating these to reduce repetition.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 811f313 and 24d8395.

📒 Files selected for processing (8)
  • src/main/webapp/app/overview/course-overview.component.html (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.scss (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (5 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html (1 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.scss (1 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (1 hunks)
  • src/test/javascript/spec/component/course/course-overview.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.scss
🧰 Additional context used
📓 Path-based instructions (3)
`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/course/course-overview.component.spec.ts
  • src/test/javascript/spec/component/course/course-sidebar.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/overview/course-overview.component.ts
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
`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/overview/course-overview.component.html
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Call Build Workflow / Build .war artifact
  • GitHub Check: Call Build Workflow / Build and Push Docker Image
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Analyse
🔇 Additional comments (53)
src/test/javascript/spec/component/course/course-overview.component.spec.ts (3)

60-60: Import of the new component added correctly.

The new CourseSidebarComponent is now properly imported for mocking in the test suite.


183-183: Good integration of the new component into test declarations.

The CourseSidebarComponent is properly mocked using MockComponent(), ensuring it's available for testing without bringing in its actual implementation dependencies.


583-593: The sidebar toggling tests are well-implemented.

The test correctly verifies that the component responds to sidebar events from the courseSidebarService, ensuring that the collapsed state is properly updated.

src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (24)

1-25: Well-structured imports for the new component test.

The imports are well-organized, including all necessary Angular testing utilities, components, and services needed for testing the sidebar component.


26-60: Clear test structure with comprehensive setup.

The test suite uses a proper setup with component fixture creation and provides mock data for courses with various configurations for testing different scenarios.


108-148: Thorough TestBed configuration and component initialization.

The test setup uses proper Angular testing patterns:

  • Comprehensive set of imports and providers
  • MockComponent/MockDirective for dependencies
  • Setting all required component inputs before detection

150-158: Good verification of component initialization methods.

The test correctly verifies that the component properly initializes visible/hidden items during component initialization by spying on the relevant methods.


160-175: Properly testing component's reaction to input changes.

The test verifies that the component recalculates hidden items when the sidebarItems input changes by properly mocking the SimpleChanges object.


177-183: Testing window resize event handling.

The test ensures the component responds to window resize events by dispatching a mock event and verifying the appropriate method is called.


185-200: Good testing of dropdown visibility logic.

The test verifies that the dropdown is properly closed when updating visible navbar items, using mocks for the NgbDropdown component.


202-210: Threshold calculation verification is accurate.

The test verifies the threshold calculation logic, ensuring it accounts for window offset and item height based on the number of sidebar items.


212-225: Comprehensive testing of item visibility threshold application.

The test verifies both scenarios:

  1. When items should be hidden (threshold > height)
  2. When all items should be visible (threshold < height)

227-234: Proper testing of course title display.

The test ensures the course title is correctly displayed when the navbar is not collapsed.


236-244: Good testing of the "more" icon visibility logic.

The test verifies that the "three dots" icon for hidden items is correctly shown or hidden based on the anyItemHidden state.


245-262: Complete testing of course icon display logic.

The tests verify both scenarios:

  1. When a course has an icon, it's properly displayed
  2. When a course has no icon, a fallback circle is displayed instead

264-271: Proper event emission testing for collapse toggle.

The test correctly verifies that clicking the collapse chevron emits the toggleCollapseState event.


273-281: Good verification of course switching event emission.

The test confirms that selecting a course from the dropdown correctly emits the switchCourse event.


283-291: Proper testing of action item click event emission.

The test verifies that clicking an action item correctly emits the courseActionItemClick event with the correct item.


293-302: Good testing of sidebar items creation with analytics dashboard.

The test verifies that when the studentCourseAnalyticsDashboardEnabled flag is true, the dashboard item is included in the sidebar items.


304-311: Proper testing of default sidebar items.

The test ensures that the default sidebar items (Exercises, Lectures) are always included regardless of other settings.


313-321: Testing exams tab visibility logic.

The test verifies that the exams tab is included and positioned correctly in the sidebar when visible exams are present.


323-335: Comprehensive testing of learning path and competencies tabs.

The test ensures that learning path and competencies tabs are included when the appropriate flags are set on the course.


337-346: Testing FAQ tab inclusion logic.

The test verifies that the FAQ tab is included when the faqEnabled flag is set on the course.


348-359: Good verification of visible exams logic.

The test correctly mocks the server date service and verifies that exams are considered visible when their visible date is before the current date.


361-372: Proper testing of exams visibility when not visible.

The test verifies that exams with a future visible date are correctly identified as not visible.


374-382: Good testing of competencies and tutorial groups detection.

The test verifies that the methods for detecting competencies and tutorial groups return the correct values based on the course properties.


384-388: Testing unenroll action item creation.

The test verifies that the unenroll action item is correctly included when the course has unenrollment enabled, a future end date, and the user is not a tutor.

src/main/webapp/app/overview/course-overview.component.scss (6)

156-171: Well-structured CSS for the sidebar collapse button.

The styling for the new .btn-sidebar-collapse class is well-organized with clear:

  • Positioning and layout properties
  • Transition effects for smooth animations
  • Proper hover and focus state styling

173-196: Good use of pseudo-elements for button styling.

The use of ::before and ::after pseudo-elements provides a clean way to implement the layered background effects for the collapse button, with appropriate z-index values and transitions.


198-212: Well-defined hover and active states.

The hover and active states for the collapse button are properly defined with clear background color changes, providing good visual feedback to users.


214-220: Proper styling for collapsed state.

The styling for the collapsed state of the button is well-implemented, with appropriate border color changes and opacity adjustments for the pseudo-elements.


222-238: Clean implementation of chevron animation.

The styling for the collapse button chevron is well-done with:

  • Proper rotation transform for the icon
  • Smooth transition effects
  • Appropriate spacing

241-243: Updated print styles for sidebar hiding.

The print styles have been updated to target the new .mat-drawer class instead of the previously used element, ensuring the sidebar is correctly hidden when printing.

src/main/webapp/app/overview/course-overview.component.html (2)

21-34: Clean integration of the new course-sidebar component.

The implementation of the <jhi-course-sidebar> component is well-structured with:

  • All necessary inputs properly bound
  • Event handlers for user interactions
  • Clean syntax with proper indentation

This refactoring significantly improves readability by encapsulating complex sidebar logic into a dedicated component.


36-36: Clean line break after component.

The empty line after the sidebar component closing tag helps maintain readability in the template.

src/main/webapp/app/overview/course-overview.component.ts (12)

16-24: No issues with revised imports.
These additional imports look appropriate for the new sidebar functionality and align well with Angular best practices.


41-41: Icon import acknowledged.
Importing facSidebar is fine and doesn't pose any conflicts.


46-46: Service import is valid.
Referencing CourseManagementService from ../course/manage/course-management.service is correct and consistent.


57-62: New service imports appear correct.
These additions for AlertService, LtiService, CourseSidebarService, PROFILE_ATLAS, and TranslateDirective integrate cleanly with the existing architecture.


69-69: Exam participation import is valid.
No issues with referencing ExamParticipationService for exam state management.


71-71: Side menu component imports.
Bringing in CourseActionItem and CourseSidebarComponent is aligned with the new sidebar architecture.


81-81: Sidenav content import is acknowledged.
Declaring MatSidenavContent in the component imports is correct for the new layout usage.


87-90: Template and directive imports look good.
Adding NgTemplateOutlet, FaIconComponent, TranslateDirective, and CourseSidebarComponent ensures the relevant functionalities are declared properly.


132-132: Dependency injection note.
inject(CourseSidebarService) is a valid modern approach in standalone components. No concerns here.


187-201: Sidebar open/close subscriptions.
The new subscriptions for open, close, and toggle events on the sidebar are straightforward and unsubscribed in ngOnDestroy. Good job preventing memory leaks.


202-214: Additional subscriptions for route/profile/exam.
Using separate subscriptions for route parameters, profile info, and exam start state is clear. They are also properly unsubscribed.


238-238: LTI subscription integration.
Subscribing to isShownViaLti$ is handled properly. Ensuring you unsubscribe in ngOnDestroy is equally good.

src/main/webapp/app/overview/course-sidebar/course-sidebar.component.html (1)

1-114: Well-structured layout and use of new Angular syntax.
The use of @if and @for is consistent with the guidelines. The collapsible design with ngbDropdown handles multiple course items logically.

src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (5)

1-45: Imports and new interfaces are clearly defined.
The introduced CourseActionItem and SidebarItem interfaces are concise and typed properly. This is a clean approach for item definitions.


60-82: New standalone component structure looks correct.
Declaring necessary imports in the @Component metadata ensures this standalone component is self-sufficient and modular.


83-93: Signal-based inputs are a modern Angular approach.
Using signals is advanced yet valid. Ensure you keep an eye on potential bridging complexities if mixing with older Angular patterns, though no issues are apparent here.


147-174: Threshold-based hiding logic.
Your approach to hiding items based on window height is a neat solution. Just be mindful of edge cases (e.g., extremely small viewport).


395-404: Unenrollment logic.
Providing a dedicated action item for student unenrollment is a clean solution. The modal integration is straightforward and fosters good UX.

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 9, 2025
@helios-aet helios-aet bot temporarily deployed to artemis-test4.artemis.cit.tum.de March 9, 2025 19:04 Inactive
@helios-aet helios-aet bot temporarily deployed to artemis-test3.artemis.cit.tum.de March 10, 2025 11:17 Inactive
@helios-aet helios-aet bot temporarily deployed to artemis-test5.artemis.cit.tum.de March 10, 2025 15:24 Inactive
ole-ve
ole-ve previously approved these changes Mar 10, 2025
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.

tested on TS5, works fine 👍

coolchock
coolchock previously approved these changes Mar 10, 2025
Copy link
Contributor

@coolchock coolchock 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 ts5 in the testing session, everything looks good to me

chrisknedl
chrisknedl previously approved these changes Mar 10, 2025
Copy link
Contributor

@chrisknedl chrisknedl 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 TS5 in a testing session, looks good.

Copy link
Contributor

@chrisknedl chrisknedl left a comment

Choose a reason for hiding this comment

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

For protocol, I also tried the exam mode steps 👍

SimonEntholzer
SimonEntholzer previously approved these changes Mar 10, 2025
Copy link
Contributor

@SimonEntholzer SimonEntholzer left a comment

Choose a reason for hiding this comment

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

Refactoring makes sense

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

🧹 Nitpick comments (3)
src/main/webapp/app/shared/util/markdown.conversion.util.ts (1)

101-150: Consider renaming MarkdownitTagClass to maintain consistent naming.
The function MarkdownitTagClass uses a mixed-casing style and could be renamed to markdownItTagClass or markdownItTagClassPlugin for consistency with typical camelCase naming in TypeScript.

-export function MarkdownitTagClass(markdown: MarkdownIt, mapping: TagClassMapping = {}): void {
+export function markdownItTagClass(markdown: MarkdownIt, mapping: TagClassMapping = {}): void {
src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (2)

92-92: New atlasEnabled input introduced.
If this is not explicitly used in the sidebar template, confirm whether it’s planned for future features or if it should be removed to reduce confusion.


114-125: Wide icon set included.
All new icons appear consistent with the needs of the sidebar. If any are no longer required, consider removing them to keep the codebase clean and reduce bundle size.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 24d8395 and 9f8d4b6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (46)
  • src/main/webapp/app/overview/course-overview.component.html (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (7 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.html (0 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (2 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (3 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (0 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (2 hunks)
  • src/test/javascript/spec/component/course/course-overview.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (0 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (0 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (4 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (1 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (0 hunks)
  • src/main/webapp/app/overview/course-overview.component.html (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (2 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (5 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (4 hunks)
  • src/test/javascript/spec/component/course/course-overview.component.spec.ts (0 hunks)
  • src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (11 hunks)
  • build.gradle (8 hunks)
  • gradle.properties (1 hunks)
  • gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • jest.config.js (1 hunks)
  • package.json (8 hunks)
  • src/main/webapp/app/exam/manage/students/exam-students.component.html (1 hunks)
  • src/main/webapp/app/exam/manage/students/upload-images/students-upload-images-button.component.ts (2 hunks)
  • src/main/webapp/app/index.d.ts (0 hunks)
  • src/main/webapp/app/shared/circular-progress-bar/circular-progress-bar.component.html (0 hunks)
  • src/main/webapp/app/shared/circular-progress-bar/circular-progress-bar.component.scss (0 hunks)
  • src/main/webapp/app/shared/circular-progress-bar/circular-progress-bar.component.ts (0 hunks)
  • src/main/webapp/app/shared/course-group/course-group.component.html (1 hunks)
  • src/main/webapp/app/shared/markdown-editor/monaco/markdown-editor-monaco.component.html (2 hunks)
  • src/main/webapp/app/shared/markdown-editor/monaco/markdown-editor-monaco.component.ts (1 hunks)
  • src/main/webapp/app/shared/metis/posting-markdown-editor/posting-markdown-editor.component.html (1 hunks)
  • src/main/webapp/app/shared/user-import/users-import-button.component.ts (2 hunks)
  • src/main/webapp/app/shared/util/markdown.conversion.util.ts (3 hunks)
  • src/test/javascript/spec/component/shared/circular-progress-bar.component.spec.ts (0 hunks)
  • src/main/webapp/app/overview/course-overview.component.html (1 hunks)
  • src/main/webapp/app/overview/course-overview.component.ts (10 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (3 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (3 hunks)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (2 hunks)
  • src/test/javascript/spec/component/course/course-overview.component.spec.ts (7 hunks)
  • src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (4 hunks)
💤 Files with no reviewable changes (5)
  • src/main/webapp/app/index.d.ts
  • src/main/webapp/app/shared/circular-progress-bar/circular-progress-bar.component.scss
  • src/test/javascript/spec/component/shared/circular-progress-bar.component.spec.ts
  • src/main/webapp/app/shared/circular-progress-bar/circular-progress-bar.component.ts
  • src/main/webapp/app/shared/circular-progress-bar/circular-progress-bar.component.html
✅ Files skipped from review due to trivial changes (3)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-overview.component.ts
  • jest.config.js
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-overview.component.html
  • src/main/webapp/app/overview/course-overview.component.ts
  • src/main/webapp/app/overview/course-overview.component.html
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-overview.component.html
  • src/main/webapp/app/overview/course-overview.component.ts
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.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/shared/course-group/course-group.component.html
  • src/main/webapp/app/shared/metis/posting-markdown-editor/posting-markdown-editor.component.html
  • src/main/webapp/app/shared/markdown-editor/monaco/markdown-editor-monaco.component.html
  • src/main/webapp/app/exam/manage/students/exam-students.component.html
  • src/main/webapp/app/overview/course-overview.component.html
`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/shared/markdown-editor/monaco/markdown-editor-monaco.component.ts
  • src/main/webapp/app/exam/manage/students/upload-images/students-upload-images-button.component.ts
  • src/main/webapp/app/shared/user-import/users-import-button.component.ts
  • src/main/webapp/app/overview/course-overview.component.ts
  • src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts
  • src/main/webapp/app/shared/util/markdown.conversion.util.ts
`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/course/course-overview.component.spec.ts
  • src/test/javascript/spec/component/course/course-sidebar.component.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Call Build Workflow / Build .war artifact
  • GitHub Check: Call Build Workflow / Build and Push Docker Image
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Analyse
🔇 Additional comments (56)
src/main/webapp/app/shared/course-group/course-group.component.html (1)

9-9: Event name is more descriptive. Good change!

Updating from (finish) to (importDone) creates a more self-documenting event name that better describes the action completion.

src/main/webapp/app/shared/user-import/users-import-button.component.ts (2)

33-33: Good renaming for better semantic clarity

Changing the output event from finish to importDone improves code readability by clearly indicating what action has completed.


52-52: Updated event emission to match renamed output

Correctly updated the event emission to use the renamed property.

src/main/webapp/app/exam/manage/students/upload-images/students-upload-images-button.component.ts (2)

32-32: Good renaming for better semantic clarity

Changing the output event from finish to uploadDone improves code readability by clearly indicating what action has completed.


48-48: Updated event emission to match renamed output

Correctly updated the event emission to use the renamed property.

src/main/webapp/app/exam/manage/students/exam-students.component.html (2)

19-19: Updated event binding to match component's output name

Correctly updated the event binding from (finish) to (importDone) to match the renamed output in the UserImportButtonComponent.


22-22: Updated event binding to match component's output name

Correctly updated the event binding from (finish) to (uploadDone) to match the renamed output in the StudentsUploadImagesButtonComponent.

src/main/webapp/app/shared/markdown-editor/monaco/markdown-editor-monaco.component.ts (1)

247-247: Appropriate addition of the isInCommunication property.

The new input property follows Angular's modern input API pattern and is correctly implemented with a default value of false. This properly follows the camelCase naming convention per Angular style guidelines.

src/main/webapp/app/shared/metis/posting-markdown-editor/posting-markdown-editor.component.html (1)

27-27: LGTM: Property binding correctly implemented.

The [isInCommunication]="true" binding is properly implemented and placed alongside other input properties. This ensures the markdown editor component knows it's being used in a communication context.

src/main/webapp/app/shared/markdown-editor/monaco/markdown-editor-monaco.component.html (2)

48-50: Correctly updated conditional display logic with modern syntax.

The condition properly uses the new Angular @if syntax as specified in the coding guidelines, and correctly adds the isInCommunication() check to ensure the send button only appears in appropriate contexts.


77-79: Consistent implementation of updated conditional logic.

This change maintains consistency with the earlier condition modification, ensuring the send button visibility logic is the same across different parts of the template.

gradle/wrapper/gradle-wrapper.properties (1)

3-3: Good update to stable Gradle version

Updating from the release candidate (rc-2) to the stable release of Gradle 8.13 is a good practice for production code.

src/test/javascript/spec/component/course/course-overview.component.spec.ts (4)

62-62: Properly importing the new component for testing

The import of CourseSidebarComponent aligns with the PR objective of refactoring the sidebar into its own component.


187-187: Good use of MockComponent for the refactored sidebar

Using MockComponent from ng-mocks is the correct approach for isolating the CourseOverviewComponent in unit tests.


266-277: Good test coverage for new sidebar methods

The test properly verifies that the new sidebar-related methods are called during initialization, which helps ensure the refactored code works correctly. The use of jest's toHaveBeenCalledOnce() also follows the test guidelines specified in the coding standards.


290-305: Comprehensive test cases for sidebar item generation

These new tests provide good coverage for the sidebar item generation logic, testing both when the analytics dashboard is enabled and the default case. This ensures the sidebar properly displays the correct navigation items in different scenarios.

gradle.properties (1)

21-51:

❓ Verification inconclusive

Good dependency version updates

Updating to the latest library versions is good practice for incorporating bug fixes and security patches. The JUnit update to 5.12.0 is more significant than the other minor version updates.

Since the JUnit version update from 5.11.4 to 5.12.0 is more significant than the other minor version bumps, it's worth verifying that there aren't any breaking changes that might affect the test suite:


🏁 Script executed:

#!/bin/bash
# Check for failing tests that might be related to the JUnit update
./gradlew test --tests "*Test" --info | grep -E "(FAILED|junit)"

Length of output: 256


Action Required: Re-run tests with a valid JAVA_HOME

The dependency updates look good overall. However, the verification script for the JUnit update couldn’t provide any meaningful output due to an environment error (JAVA_HOME is set to an invalid directory), so we can’t confirm that no tests broke with JUnit 5.12.0. Please manually re-run the tests after setting JAVA_HOME to a valid Java installation. For example:

export JAVA_HOME=/path/to/valid/java-installation
./gradlew test --tests "*Test" --info | grep -E "(FAILED|junit)"

Once you verify that the tests pass without issues, please update the status accordingly.

src/test/javascript/spec/component/course/course-sidebar.component.spec.ts (7)

10-24: Good use of modern testing imports and utilities

The test file correctly imports the necessary testing utilities and uses MockProvider from ng-mocks, which aligns with the specified coding guidelines. Adding the ArtemisServerDateService and dayjs imports ensures proper date handling capabilities in the tests.


37-49: Well-structured test data with comprehensive properties

The test courses have been enhanced with all the necessary properties to thoroughly test sidebar functionality, including competencies, tutorial groups, and prerequisites counts that would affect sidebar display.


131-131: Properly mocking the server date service

Using MockProvider for ArtemisServerDateService ensures the tests run deterministically without actual server dependencies.


139-147: Modern component input initialization

Using fixture.componentRef.setInput() instead of direct property assignment follows best practices for Angular component testing, making the test more resilient to Angular's change detection mechanisms.


150-158: Comprehensive initialization testing

Good practice to verify that all necessary methods are called during component initialization, with proper parameter validation.


161-225: Good use of Angular signals for state management

The test uses Angular's signal-based reactivity system (using .set() methods and function-style accessors like anyItemHidden()) which represents a more modern and robust approach compared to direct property access.


228-256: Thorough testing of UI state transitions

The tests properly verify how the component responds to changes in inputs and state, testing both the behavior and the visual display aspects of the sidebar.

src/main/webapp/app/overview/course-overview.component.html (1)

21-37: Consider passing the new atlasEnabled property for consistency.
The <jhi-course-sidebar> component now supports an atlasEnabled input, but it's not used here. If this functionality is relevant in the overview, you may want to pass it as an input to keep the component configuration consistent with its declarations.

src/main/webapp/app/shared/util/markdown.conversion.util.ts (1)

53-78: Validate plugin ordering to avoid unintentional token modifications.
You're chaining multiple MarkdownIt extensions, which can potentially introduce ordering constraints (e.g., if one plugin transforms tokens that another plugin depends upon). Verify that the final rendering aligns with your expectations and that none of the plugin transformations conflict.

build.gradle (9)

22-22: Confirm plugin compatibility.
Updating com.gorylenko.gradle-git-properties plugin to 2.5.0 generally works well, but ensure no breaking changes occurred in how Git properties are generated and consumed.


40-40: Check Gradle 8.13 stability.
Upgrading to Gradle 8.13 may impact certain plugins or scripts that rely on prior behavior. Verify that the build and all tasks, including Docker tasks, run successfully with this version.


108-108: Excluding legacy JUnit from the classpath.
Removing the old JUnit dependency is recommended when migrating fully to JUnit 5. No concerns here.


162-162: Verify new GitLab4J API version.
Upgrading from rc.8 to rc.9 is typically minor, but ensure that any feature usage in the GitLab4J library remains compatible.


227-227: Check for newer jsoup versions.
jsoup:1.19.1 is relatively recent, but it's good to confirm if a patch or minor update like 1.19.2 exists to address potential bugs or security issues.


326-326: Ensure no security advisories for Nimbus.
com.nimbusds:nimbus-jose-jwt:10.0.2 is a recent version, but double-check for any new security advisories or patches.


415-415: Validate Gradle Tooling API updates.
Including org.gradle:gradle-tooling-api:8.13 should match your Gradle wrapper. Confirm compatibility to avoid version mismatch.


429-433: Good transition to JUnit 5.
Adopting the JUnit 5 libraries (org.junit.jupiter) is a best practice and aligns with modern testing frameworks. No issues found.


435-436: JUnit Platform additions.
Introducing platform dependencies (junit-platform-commons and junit-platform-engine) further solidifies the JUnit 5 setup. Looks good.

src/main/webapp/app/overview/course-sidebar/course-sidebar.component.ts (5)

83-85: Enforcing non-nullable course inputs.
Switching from Course | undefined to Course ensures the course is always provided. Verify that upstream callers satisfy this new requirement to avoid runtime errors.


96-97: Migrating to signals for sidebar items.
This approach can simplify reactivity. Ensure change detection is triggered properly and that the rest of your code listens for these signal updates.


99-99: canUnenroll signal addition.
Make sure to handle this signal in the template or other logic if the unenrollment feature is fully implemented. Otherwise, it could be misleading to have an unused state variable.


127-128: Using Angular's DI with inject().
This is a modern approach in Angular. Just be mindful that this pattern can complicate testing if providers aren't configured properly in your test setup.


130-134: Initializing sidebar items and action items on ngOnInit.
Good practice—ensures the data is ready before change detection runs. Validate any external dependencies or asynchronous fetches if they’re integrated within these initialization functions.

src/main/webapp/app/overview/course-overview.component.ts (12)

23-23: Appropriate imports added for the new sidebar functionality.

The imports are well organized and include all necessary modules for the new sidebar component implementation.

Also applies to: 63-64, 77-77, 81-81, 110-111, 117-118


144-147: Good addition of strongly typed properties for sidebar functionality.

The new properties sidebarItems, courseActionItems, and canUnenroll are properly typed using appropriate interfaces, improving code robustness and maintainability.


253-254: Excellent initialization of sidebar items in ngOnInit.

The initialization of sidebar items and course action items is appropriately placed in the ngOnInit lifecycle hook, ensuring that these items are created when the component is initialized.


289-297: Well-structured method for generating course action items.

The getCourseActionItems method cleanly implements the logic for determining available actions for the current course, with proper conditional logic for the unenroll functionality.


299-334: Excellent implementation of sidebar items generation.

The getSidebarItems method is well organized and follows a clear pattern to build the sidebar dynamically based on course properties. The code makes good use of the helper methods to create specific items and appropriately positions them in the sidebar.


336-344: Clean implementation of unenroll item creation.

The getUnenrollItem method creates a properly structured action item with all required properties, including the translation key and action callback.


346-480: Great modularization of sidebar item creation methods.

Breaking down the sidebar item creation into individual methods for each type of item (lectures, exams, communications, etc.) improves code readability and maintenance. Each method returns a properly structured item with all necessary properties.


510-512: Good implementation of student unenrollment check.

The canStudentUnenroll method performs a proper validation by checking both the course's unenrollment flag and the current date against the unenrollment end date.


520-523: Properly implemented modal opening for student unenrollment.

The openUnenrollStudentModal method correctly uses the NgbModal service to open the unenrollment modal dialog and passes the current course to the modal component.


756-765: Well-implemented visibility check for exams.

The hasVisibleExams method correctly iterates through the course's exams to determine if any should be visible based on their visibility date compared to the current server date.


770-772: Concise competencies check method.

The hasCompetencies method efficiently checks for the presence of competencies or prerequisites using a nullish coalescing operator.


777-779: Effective tutorial groups check.

The hasTutorialGroups method uses a concise approach to determine if the course has any tutorial groups.

package.json (4)

16-27: Angular dependencies updated to consistent versions.

The Angular packages have been updated to matching versions (19.2.1/19.2.2), ensuring compatibility between the core framework and related libraries.


39-39: Third-party library versions updated.

Dependencies like Sentry, core-js, and simple-statistics have been updated to newer versions, which likely include bug fixes and security improvements.

Also applies to: 47-47, 75-75


104-104: Build tool dependencies properly updated.

Build-related packages like ESLint and Vite have been updated to their latest compatible versions.

Also applies to: 112-113, 127-127


137-147: Development dependencies consistently updated.

The Angular ESLint packages, TypeScript-related libraries, and testing tools have been updated to ensure a consistent development environment.

Also applies to: 155-164, 166-168, 184-191

@helios-aet helios-aet bot temporarily deployed to artemis-test4.artemis.cit.tum.de March 12, 2025 20:10 Inactive
Copy link
Contributor

@SimonEntholzer SimonEntholzer left a comment

Choose a reason for hiding this comment

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

Re-approve, and tested on Ts4.

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 for review tests
Projects
Status: Work In Progress
Development

Successfully merging this pull request may close these issues.

5 participants