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

Communication: Migrate Metis to standalone components #9904

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { LinkPreview, LinkPreviewService } from 'app/shared/link-preview/service
import { Link, LinkifyService } from 'app/shared/link-preview/services/linkify.service';
import { User } from 'app/core/user/user.model';
import { Posting } from 'app/entities/metis/posting.model';
import { LinkPreviewComponent } from 'app/shared/link-preview/components/link-preview/link-preview.component';

@Component({
selector: 'jhi-link-preview-container',
templateUrl: './link-preview-container.component.html',
styleUrls: ['./link-preview-container.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [LinkPreviewComponent],
})
export class LinkPreviewContainerComponent implements OnInit, OnChanges {
private readonly linkPreviewService: LinkPreviewService = inject(LinkPreviewService);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnInit, inject } from '@angular/core';
import { LinkPreview } from 'app/shared/link-preview/services/link-preview.service';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import { MetisService } from 'app/shared/metis/metis.service';
import { Posting } from 'app/entities/metis/posting.model';
import { urlRegex } from 'app/shared/link-preview/services/linkify.service';
import { ArtemisConfirmIconModule } from 'app/shared/confirm-icon/confirm-icon.module';
import { ArtemisSharedModule } from 'app/shared/shared.module';

@Component({
selector: 'jhi-link-preview',
templateUrl: './link-preview.component.html',
styleUrls: ['./link-preview.component.scss'],
standalone: true,
imports: [ArtemisConfirmIconModule, ArtemisSharedModule],
})
export class LinkPreviewComponent implements OnInit {
@Input() linkPreview: LinkPreview;
Expand All @@ -23,7 +27,7 @@ export class LinkPreviewComponent implements OnInit {

faTimes = faTimes;

constructor(private metisService: MetisService) {}
private metisService = inject(MetisService);

ngOnInit() {
this.isAuthorOfOriginalPost = this.metisService.metisUserIsAuthorOfPosting(this.posting!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import {
Component,
EventEmitter,
HostListener,
Inject,
Input,
OnChanges,
OnInit,
Output,
Renderer2,
ViewChild,
ViewContainerRef,
inject,
input,
} from '@angular/core';
import { AnswerPost } from 'app/entities/metis/answer-post.model';
Expand All @@ -23,6 +23,12 @@ import { Reaction } from 'app/entities/metis/reaction.model';
import { faBookmark, faPencilAlt, faSmile, faTrash } from '@fortawesome/free-solid-svg-icons';
import { DOCUMENT } from '@angular/common';
import { AnswerPostReactionsBarComponent } from 'app/shared/metis/posting-reactions-bar/answer-post-reactions-bar/answer-post-reactions-bar.component';
import { PostingContentComponent } from 'app/shared/metis/posting-content/posting-content.components';
cremertim marked this conversation as resolved.
Show resolved Hide resolved
import { AnswerPostHeaderComponent } from 'app/shared/metis/posting-header/answer-post-header/answer-post-header.component';
import { AnswerPostCreateEditModalComponent } from 'app/shared/metis/posting-create-edit-modal/answer-post-create-edit-modal/answer-post-create-edit-modal.component';
import { OverlayModule } from '@angular/cdk/overlay';
import { EmojiPickerComponent } from 'app/shared/metis/emoji/emoji-picker.component';
import { ArtemisSharedModule } from 'app/shared/shared.module';

@Component({
selector: 'jhi-answer-post',
Expand All @@ -35,6 +41,16 @@ import { AnswerPostReactionsBarComponent } from 'app/shared/metis/posting-reacti
transition(':leave', [animate('300ms ease-out', style({ opacity: 0 }))]),
]),
],
standalone: true,
imports: [
AnswerPostReactionsBarComponent,
PostingContentComponent,
AnswerPostHeaderComponent,
AnswerPostCreateEditModalComponent,
ArtemisSharedModule,
OverlayModule,
EmojiPickerComponent,
],
Comment on lines +44 to +53
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

ArtemisSharedModule import can be replaced with specific imports

Based on the template analysis, the component only uses basic Angular directives (ngClass, ngStyle, ngIf) and the jhiTranslate directive. These can be imported directly from their respective modules:

  • Replace ArtemisSharedModule with:
    • CommonModule from @angular/common for ngClass, ngStyle, ngIf
    • TranslateModule from @ngx-translate/core for jhiTranslate
🔗 Analysis chain

Verify the necessity of ArtemisSharedModule import

While the standalone configuration looks good, importing ArtemisSharedModule might go against the standalone component migration objective. Consider extracting only the needed dependencies from this module.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check what dependencies from ArtemisSharedModule are actually used in this component
ast-grep --pattern 'import { ArtemisSharedModule } from "app/shared/shared.module"'

# Find template usage
rg -l "ArtemisSharedModule" "src/main/webapp/app/shared/metis/answer-post/answer-post.component.html"

Length of output: 185


Script:

#!/bin/bash
# Let's first check the content of the component file to understand its dependencies
cat "src/main/webapp/app/shared/metis/answer-post/answer-post.component.ts"

# Let's also check the template file to see what features are being used
cat "src/main/webapp/app/shared/metis/answer-post/answer-post.component.html"

# Let's examine what ArtemisSharedModule exports
rg -A 10 "export class ArtemisSharedModule" 

Length of output: 11634


Script:

#!/bin/bash
# Let's check what directives and pipes are being used in the template
rg "ng[A-Z]\w+" "src/main/webapp/app/shared/metis/answer-post/answer-post.component.html"

# Let's also check what the shared module imports and exports
cat "src/main/webapp/app/shared/shared.module.ts"

Length of output: 6118

})
export class AnswerPostComponent extends PostingDirective<AnswerPost> implements OnInit, OnChanges {
@Input() lastReadDate?: dayjs.Dayjs;
Expand All @@ -61,13 +77,9 @@ export class AnswerPostComponent extends PostingDirective<AnswerPost> implements
mayDelete: boolean = false;
@ViewChild(AnswerPostReactionsBarComponent) private reactionsBarComponent!: AnswerPostReactionsBarComponent;

constructor(
public changeDetector: ChangeDetectorRef,
public renderer: Renderer2,
@Inject(DOCUMENT) private document: Document,
) {
super();
}
public changeDetector = inject(ChangeDetectorRef);
private renderer = inject(Renderer2);
private document = inject(DOCUMENT);

ngOnInit() {
super.ngOnInit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import { Component, EventEmitter, Input, Output, computed, inject } from '@angul
import { Theme, ThemeService } from 'app/core/theme/theme.service';
import { EmojiUtils } from 'app/shared/metis/emoji/emoji.utils';
import { EmojiData } from '@ctrl/ngx-emoji-mart/ngx-emoji';
import { EmojiModule } from '@ctrl/ngx-emoji-mart/ngx-emoji';
import { ArtemisSharedModule } from 'app/shared/shared.module';
import { PickerModule } from '@ctrl/ngx-emoji-mart';

@Component({
selector: 'jhi-emoji-picker',
templateUrl: './emoji-picker.component.html',
standalone: true,
imports: [EmojiModule, ArtemisSharedModule, PickerModule],
})
export class EmojiPickerComponent {
private themeService = inject(ThemeService);
Expand Down
3 changes: 3 additions & 0 deletions src/main/webapp/app/shared/metis/emoji/emoji.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Component, Input, computed, inject } from '@angular/core';
import { Theme, ThemeService } from 'app/core/theme/theme.service';
import { EmojiUtils } from 'app/shared/metis/emoji/emoji.utils';
import { EmojiModule } from '@ctrl/ngx-emoji-mart/ngx-emoji';

@Component({
selector: 'jhi-emoji',
templateUrl: './emoji.component.html',
styleUrls: ['./emoji.component.scss'],
standalone: true,
imports: [EmojiModule],
Comment on lines +10 to +11
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Migration to standalone component is incomplete - component is still declared in MetisModule

The EmojiComponent has been configured as standalone but is still both imported and exported in the MetisModule. This is incorrect as standalone components should not be declared in NgModules. The component needs to be removed from both the imports and exports arrays of MetisModule.

  • Remove EmojiComponent from the imports array in src/main/webapp/app/shared/metis/metis.module.ts
  • Remove EmojiComponent from the exports array in src/main/webapp/app/shared/metis/metis.module.ts
🔗 Analysis chain

LGTM! Standalone component migration looks correct.

The component has been properly configured as standalone with the necessary imports. This aligns with the PR objective of migrating Metis to standalone components and follows Angular's standalone component patterns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify this component is no longer declared in any NgModule

# Search for any remaining module declarations of this component
ast-grep --pattern 'NgModule({
  $$$
  declarations: [
    $$$
    EmojiComponent,
    $$$
  ]
  $$$
})'

Length of output: 230


Script:

#!/bin/bash
# Let's try a different approach to verify the component's migration
# First, let's find any NgModule that might reference EmojiComponent
rg "EmojiComponent" -l

# Then, let's also verify the component's standalone configuration
rg "standalone.*true" --type ts

# And check for any potential module files in the same directory
fd "module\.ts$" -p src/main/webapp/app/shared/metis/emoji/

Length of output: 19479


Script:

#!/bin/bash
# Let's examine the metis.module.ts file since it references EmojiComponent
cat src/main/webapp/app/shared/metis/metis.module.ts

Length of output: 6528

})
export class EmojiComponent {
private themeService = inject(ThemeService);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core';
import { AnswerPost } from 'app/entities/metis/answer-post.model';
import { MetisService } from 'app/shared/metis/metis.service';
import { FormBuilder, Validators } from '@angular/forms';
import { Validators } from '@angular/forms';
import { Post } from 'app/entities/metis/post.model';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { PostContentValidationPattern } from 'app/shared/metis/metis.util';
import { PostingCreateEditDirective } from 'app/shared/metis/posting-create-edit.directive';
import { LocalStorageService } from 'ngx-webstorage';
import { ArtemisSharedModule } from 'app/shared/shared.module';
import { PostingButtonComponent } from 'app/shared/metis/posting-button/posting-button.component';
import { PostingMarkdownEditorComponent } from 'app/shared/metis/posting-markdown-editor/posting-markdown-editor.component';

@Component({
selector: 'jhi-message-inline-input',
templateUrl: './message-inline-input.component.html',
styleUrls: ['./message-inline-input.component.scss'],
encapsulation: ViewEncapsulation.None,
standalone: true,
imports: [ArtemisSharedModule, PostingButtonComponent, PostingMarkdownEditorComponent],
})
Comment on lines +17 to +18
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Consider selective imports and encapsulation changes

  1. The component is importing the entire ArtemisSharedModule but only needs the common Angular features which are already available through standalone imports. The shared module can be removed as PostingButtonComponent and PostingMarkdownEditorComponent are already imported separately.

  2. The component uses ViewEncapsulation.None which can lead to style leaks. Given the presence of a dedicated SCSS file (message-inline-input.component.scss), the component should use the default encapsulation mode to properly scope its styles.

  • Remove ArtemisSharedModule from imports as it's not needed in standalone components
  • Change encapsulation: ViewEncapsulation.None to use default encapsulation or explicitly set it to ViewEncapsulation.Emulated
🔗 Analysis chain

Verify shared module imports and encapsulation.

Two considerations:

  1. Consider importing only the needed components/directives from ArtemisSharedModule to reduce bundle size
  2. Using ViewEncapsulation.None might lead to style leaks. Ensure styles are properly scoped.

Let's check the shared module imports and style usage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check shared module exports and style usage

# Find shared module exports
echo "Checking shared module exports:"
rg -A 10 "export class ArtemisSharedModule" src/

# Check for style references to this component
echo "Checking style references:"
rg -l "jhi-message-inline-input" src/ --type css --type scss

Length of output: 356


Script:

#!/bin/bash
# Let's check the shared module content and style encapsulation

# Check shared module content
echo "Checking shared module content:"
cat src/main/webapp/app/shared/shared.module.ts

# Check component's style encapsulation
echo -e "\nChecking component's style encapsulation:"
rg -A 5 "@Component" src/main/webapp/app/shared/metis/message/message-inline-input/message-inline-input.component.ts

# Check for style files with correct extension
echo -e "\nChecking style files:"
fd -e scss -e css . src/main/webapp/app/shared/metis/message/message-inline-input/

# Check imports in the component
echo -e "\nChecking component imports:"
rg "import.*from.*shared" src/main/webapp/app/shared/metis/message/message-inline-input/message-inline-input.component.ts

Length of output: 6250

export class MessageInlineInputComponent extends PostingCreateEditDirective<Post | AnswerPost> implements OnInit {
warningDismissed = false;

constructor(
protected metisService: MetisService,
protected modalService: NgbModal,
protected formBuilder: FormBuilder,
protected localStorageService: LocalStorageService,
) {
super(metisService, modalService, formBuilder);
}
protected localStorageService = inject(LocalStorageService);

ngOnInit(): void {
super.ngOnInit();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { Component, EventEmitter, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation, input } from '@angular/core';
import { Component, EventEmitter, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation, inject, input } from '@angular/core';
import { AnswerPost } from 'app/entities/metis/answer-post.model';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { MetisService } from 'app/shared/metis/metis.service';
import { FormBuilder, Validators } from '@angular/forms';
import { Validators } from '@angular/forms';
import { PostContentValidationPattern } from 'app/shared/metis/metis.util';
import { PostingCreateEditDirective } from 'app/shared/metis/posting-create-edit.directive';
import { LocalStorageService } from 'ngx-webstorage';
import { ConversationDTO } from 'app/entities/metis/conversation/conversation.model';
import { PostingButtonComponent } from 'app/shared/metis/posting-button/posting-button.component';
import { ArtemisSharedModule } from 'app/shared/shared.module';
import { PostingMarkdownEditorComponent } from 'app/shared/metis/posting-markdown-editor/posting-markdown-editor.component';

@Component({
selector: 'jhi-message-reply-inline-input',
templateUrl: './message-reply-inline-input.component.html',
styleUrls: ['./message-reply-inline-input.component.scss'],
encapsulation: ViewEncapsulation.None,
standalone: true,
imports: [PostingButtonComponent, ArtemisSharedModule, PostingMarkdownEditorComponent],
})
export class MessageReplyInlineInputComponent extends PostingCreateEditDirective<AnswerPost> implements OnInit, OnChanges {
warningDismissed = false;
Expand All @@ -22,14 +25,7 @@ export class MessageReplyInlineInputComponent extends PostingCreateEditDirective
@Output()
valueChange = new EventEmitter<void>();

constructor(
protected metisService: MetisService,
protected modalService: NgbModal,
protected formBuilder: FormBuilder,
protected localStorageService: LocalStorageService,
) {
super(metisService, modalService, formBuilder);
}
protected localStorageService = inject(LocalStorageService);

ngOnInit(): void {
super.ngOnInit();
Expand Down
35 changes: 17 additions & 18 deletions src/main/webapp/app/shared/metis/metis.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,15 @@ import { ProfilePictureComponent } from 'app/shared/profile-picture/profile-pict
ReactiveFormsModule,
FormsModule,
ArtemisSharedComponentModule,
PostReactionsBarComponent,
AnswerPostReactionsBarComponent,
PostCreateEditModalComponent,
PickerModule,
EmojiComponent,
EmojiPickerComponent,
EmojiModule,
PostingMarkdownEditorComponent,
PostComponent,
OverlayModule,
CommonModule,
FontAwesomeModule,
Expand All @@ -64,32 +71,23 @@ import { ProfilePictureComponent } from 'app/shared/profile-picture/profile-pict
MatDialogModule,
LinkPreviewModule,
ProfilePictureComponent,
],
declarations: [
PostingThreadComponent,
PostHeaderComponent,
AnswerPostHeaderComponent,
PostCreateEditModalComponent,
ReactingUsersOnPostingPipe,
PostTagSelectorComponent,
PostFooterComponent,
PostingContentComponent,
AnswerPostCreateEditModalComponent,
PostingButtonComponent,
PostingMarkdownEditorComponent,
PostComponent,
AnswerPostComponent,
PostingContentComponent,
PostingContentPartComponent,
LinkPreviewComponent,
LinkPreviewContainerComponent,
EnlargeSlideImageComponent,
PostReactionsBarComponent,
AnswerPostReactionsBarComponent,
MessageInlineInputComponent,
MessageReplyInlineInputComponent,
PostingContentPartComponent,
PostHeaderComponent,
AnswerPostHeaderComponent,
PostingButtonComponent,
HtmlForPostingMarkdownPipe,
ReactingUsersOnPostingPipe,
EmojiComponent,
EmojiPickerComponent,
PostingThreadComponent,
EnlargeSlideImageComponent,
MessageReplyInlineInputComponent,
],
exports: [
PostingThreadComponent,
Expand All @@ -115,6 +113,7 @@ import { ProfilePictureComponent } from 'app/shared/profile-picture/profile-pict
HtmlForPostingMarkdownPipe,
EmojiComponent,
EmojiPickerComponent,
ReactingUsersOnPostingPipe,
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Redundant export of standalone pipe confirmed

The pipe is correctly marked as standalone and is being directly imported from its source file (app/shared/pipes/reacting-users-on-posting.pipe) by the components that use it. There's no usage through the metis.module, making its export redundant.

  • Remove ReactingUsersOnPostingPipe from the exports array in src/main/webapp/app/shared/metis/metis.module.ts
🔗 Analysis chain

Review necessity of exporting standalone pipe

Since ReactingUsersOnPostingPipe is marked as standalone, it might not need to be exported from the module. Standalone pipes can be imported directly where needed.

Consider removing the pipe from exports if it's not specifically required through the module import.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the pipe is actually used through the module export
rg -l "import.*ReactingUsersOnPostingPipe.*from.*metis\.module" 

Length of output: 65


Script:

#!/bin/bash
# Let's check how the pipe is imported in other files
rg -l "import.*ReactingUsersOnPostingPipe"

# Also check the pipe's implementation to verify if it's standalone
fd -e ts "ReactingUsersOnPostingPipe" --exec cat {}

Length of output: 710


Script:

#!/bin/bash
# Let's check the actual implementation of the pipe and its imports
ast-grep --pattern 'import { ReactingUsersOnPostingPipe } from $_'

# And check the pipe's implementation to verify standalone decorator
ast-grep --pattern '@Pipe({
  $$$
  standalone: true,
  $$$
})'

Length of output: 1835


Script:

#!/bin/bash
# Let's check how the components are importing this pipe
rg "import.*ReactingUsersOnPostingPipe" -A 2 src/main/webapp/app/shared/metis/posting-reactions-bar/

Length of output: 2492

],
providers: [MetisConversationService],
})
Expand Down
41 changes: 25 additions & 16 deletions src/main/webapp/app/shared/metis/post/post.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import {
AfterContentChecked,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
HostListener,
Inject,
Input,
OnChanges,
OnInit,
Output,
Renderer2,
ViewChild,
ViewContainerRef,
inject,
input,
Comment on lines +14 to 15
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect Angular import

The input import on line 15 appears to be incorrect. Angular's decorator should be capitalized as Input.

- import { inject, input } from '@angular/core';
+ import { inject, Input } from '@angular/core';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
inject,
input,
inject,
Input,

} from '@angular/core';
import { Post } from 'app/entities/metis/post.model';
import { PostingDirective } from 'app/shared/metis/posting.directive';
import { MetisService } from 'app/shared/metis/metis.service';
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ContextInformation, DisplayPriority, PageType, RouteComponents } from '../metis.util';
import { faBookmark, faBullhorn, faCheckSquare, faComments, faPencilAlt, faSmile, faThumbtack, faTrash } from '@fortawesome/free-solid-svg-icons';
import dayjs from 'dayjs/esm';
Expand All @@ -33,8 +30,14 @@ import { AnswerPostCreateEditModalComponent } from 'app/shared/metis/posting-cre
import { animate, style, transition, trigger } from '@angular/animations';
import { PostCreateEditModalComponent } from 'app/shared/metis/posting-create-edit-modal/post-create-edit-modal/post-create-edit-modal.component';
import { PostReactionsBarComponent } from 'app/shared/metis/posting-reactions-bar/post-reactions-bar/post-reactions-bar.component';
import { CdkOverlayOrigin } from '@angular/cdk/overlay';
import { CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
import { DOCUMENT } from '@angular/common';
import { EmojiPickerComponent } from 'app/shared/metis/emoji/emoji-picker.component';
import { ArtemisSharedModule } from 'app/shared/shared.module';
import { MessageInlineInputComponent } from 'app/shared/metis/message/message-inline-input/message-inline-input.component';
import { PostingContentComponent } from 'app/shared/metis/posting-content/posting-content.components';
import { PostHeaderComponent } from 'app/shared/metis/posting-header/post-header/post-header.component';
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref';

@Component({
selector: 'jhi-post',
Expand All @@ -47,6 +50,18 @@ import { DOCUMENT } from '@angular/common';
transition(':leave', [animate('300ms ease-out', style({ opacity: 0 }))]),
]),
],
standalone: true,
imports: [
EmojiPickerComponent,
OverlayModule,
ArtemisSharedModule,
MessageInlineInputComponent,
PostFooterComponent,
PostReactionsBarComponent,
AnswerPostCreateEditModalComponent,
PostingContentComponent,
PostHeaderComponent,
],
})
export class PostComponent extends PostingDirective<Post> implements OnInit, OnChanges, AfterContentChecked {
@Input() lastReadDate?: dayjs.Dayjs;
Expand Down Expand Up @@ -95,17 +110,11 @@ export class PostComponent extends PostingDirective<Post> implements OnInit, OnC
dropdownPosition = { x: 0, y: 0 };
@ViewChild(PostReactionsBarComponent) protected reactionsBarComponent!: PostReactionsBarComponent;

constructor(
public metisService: MetisService,
public changeDetector: ChangeDetectorRef,
private oneToOneChatService: OneToOneChatService,
private metisConversationService: MetisConversationService,
private router: Router,
public renderer: Renderer2,
@Inject(DOCUMENT) private document: Document,
) {
super();
}
private oneToOneChatService = inject(OneToOneChatService);
private metisConversationService = inject(MetisConversationService);
private router = inject(Router);
public renderer = inject(Renderer2);
private document = inject(DOCUMENT);
Comment on lines +113 to +117
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Potential subscription memory leak found

The component has unmanaged subscriptions in onUserReferenceClicked() method that are not being cleaned up:

  • this.metisConversationService.createOneToOneChat(referencedUserLogin).subscribe()
  • this.oneToOneChatService.create(course.id!, referencedUserLogin).subscribe()

Issues:

  • Component doesn't implement OnDestroy
  • No subscription cleanup mechanism present
  • Fire-and-forget subscriptions without proper error handling
🔗 Analysis chain

LGTM: Modern dependency injection pattern implemented

The migration to using inject() function follows modern Angular practices and improves code readability.

Let's verify proper subscription handling throughout the component:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for subscription patterns that might cause memory leaks
ast-grep --pattern 'subscribe($$$)' 

Length of output: 161


Script:

#!/bin/bash
# Let's try a more specific search for subscription patterns in the component file
rg -U "subscribe\(" src/main/webapp/app/shared/metis/post/post.component.ts -A 2

# Also search for OnDestroy implementation and unsubscribe patterns
rg "implements.*OnDestroy" src/main/webapp/app/shared/metis/post/post.component.ts
rg "unsubscribe" src/main/webapp/app/shared/metis/post/post.component.ts

# Check the component's complete content to analyze subscription handling
cat src/main/webapp/app/shared/metis/post/post.component.ts

Length of output: 12438


get reactionsBar() {
return this.reactionsBarComponent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Component, HostBinding, Input } from '@angular/core';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons';

@Component({
/* eslint-disable-next-line @angular-eslint/component-selector */
selector: 'button[jhi-posting-button]',
templateUrl: './posting-button.component.html',
standalone: true,
imports: [FontAwesomeModule],
})
export class PostingButtonComponent {
@Input() buttonIcon: IconProp;
Expand Down
Loading
Loading