diff --git a/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.html b/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.html
index cf04ba6cb70a..91d207a889f6 100644
--- a/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.html
+++ b/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.html
@@ -1,13 +1,13 @@
-@for (preview of linkPreviews; track trackLinks($index, preview)) {
+@for (preview of linkPreviews(); track trackLinks($index, preview)) {
}
diff --git a/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.ts b/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.ts
index 6234e60bae60..1349476f4d0c 100644
--- a/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.ts
+++ b/src/main/webapp/app/shared/link-preview/components/link-preview-container/link-preview-container.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, OnChanges, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, Component, OnChanges, OnInit, inject, input, signal } from '@angular/core';
import { LinkPreview, LinkPreviewService } from 'app/shared/link-preview/services/link-preview.service';
import { Link, LinkifyService } from 'app/shared/link-preview/services/linkify.service';
import { User } from 'app/core/user/user.model';
@@ -8,45 +8,41 @@ import { Posting } from 'app/entities/metis/posting.model';
selector: 'jhi-link-preview-container',
templateUrl: './link-preview-container.component.html',
styleUrls: ['./link-preview-container.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LinkPreviewContainerComponent implements OnInit, OnChanges {
- @Input() data: string | undefined;
- @Input() author?: User;
- @Input() posting?: Posting;
- @Input() isEdited?: boolean;
- @Input() isReply?: boolean;
+ private readonly linkPreviewService: LinkPreviewService = inject(LinkPreviewService);
+ private readonly linkifyService: LinkifyService = inject(LinkifyService);
- linkPreviews: LinkPreview[] = [];
- hasError: boolean;
- loaded = false;
- showLoadingsProgress = true;
- multiple = false;
+ readonly data = input();
+ readonly author = input();
+ readonly posting = input();
+ readonly isEdited = input();
+ readonly isReply = input();
- constructor(
- public linkPreviewService: LinkPreviewService,
- public linkifyService: LinkifyService,
- ) {}
+ readonly linkPreviews = signal([]);
+ readonly hasError = signal(false);
+ readonly loaded = signal(false);
+ readonly showLoadingsProgress = signal(true);
+ readonly multiple = signal(false);
ngOnInit() {
- this.data = this.data ?? '';
this.findPreviews();
}
ngOnChanges() {
- if (this.isEdited) {
- this.reloadLinkPreviews();
- }
+ this.reloadLinkPreviews();
}
private reloadLinkPreviews() {
- this.loaded = false;
- this.showLoadingsProgress = true;
- this.linkPreviews = []; // Clear the existing link previews
+ this.loaded.set(false);
+ this.showLoadingsProgress.set(true);
+ this.linkPreviews.set([]); // Clear the existing link previews
this.findPreviews();
}
private findPreviews() {
- const links: Link[] = this.linkifyService.find(this.data!);
+ const links: Link[] = this.linkifyService.find(this.data() ?? '');
// TODO: The limit of 5 link previews should be configurable (maybe in course level)
links
.filter((link) => !link.isLinkPreviewRemoved)
@@ -56,17 +52,21 @@ export class LinkPreviewContainerComponent implements OnInit, OnChanges {
next: (linkPreview) => {
linkPreview.shouldPreviewBeShown = !!(linkPreview.url && linkPreview.title && linkPreview.description && linkPreview.image);
- const existingLinkPreview = this.linkPreviews.find((preview) => preview.url === linkPreview.url);
- if (existingLinkPreview) {
- Object.assign(existingLinkPreview, linkPreview);
+ const existingLinkPreviewIndex = this.linkPreviews().findIndex((preview) => preview.url === linkPreview.url);
+ if (existingLinkPreviewIndex !== -1) {
+ this.linkPreviews.update((previews) => {
+ const existingLinkPreview = previews[existingLinkPreviewIndex];
+ Object.assign(existingLinkPreview, linkPreview);
+ return previews;
+ });
} else {
- this.linkPreviews.push(linkPreview);
+ this.linkPreviews.set([...this.linkPreviews(), linkPreview]);
}
- this.hasError = false;
- this.loaded = true;
- this.showLoadingsProgress = false;
- this.multiple = this.linkPreviews.length > 1;
+ this.hasError.set(false);
+ this.loaded.set(true);
+ this.showLoadingsProgress.set(false);
+ this.multiple.set(this.linkPreviews().length > 1);
},
});
});
diff --git a/src/test/javascript/spec/component/link-preview/link-preview-container.component.spec.ts b/src/test/javascript/spec/component/link-preview/link-preview-container.component.spec.ts
index 6f17eeba735a..534aaad61e6f 100644
--- a/src/test/javascript/spec/component/link-preview/link-preview-container.component.spec.ts
+++ b/src/test/javascript/spec/component/link-preview/link-preview-container.component.spec.ts
@@ -37,7 +37,7 @@ describe('LinkPreviewContainerComponent', () => {
});
it('should fetch link previews and update linkPreviews array', () => {
- component.data = 'Check out these links: https://example.com/link1 and https://example.com/link2';
+ fixture.componentRef.setInput('data', 'Check out these links: https://example.com/link1 and https://example.com/link2');
const links: Link[] = [
{ type: '', value: '', href: 'https://example.com/link1' },
{ type: '', value: '', href: 'https://example.com/link2' },
@@ -52,18 +52,18 @@ describe('LinkPreviewContainerComponent', () => {
component.ngOnInit();
- expect(linkifyServiceSpy).toHaveBeenCalledWith(component.data);
+ expect(linkifyServiceSpy).toHaveBeenCalledWith(component.data());
expect(linkPreviewServiceSpy).toHaveBeenCalledTimes(2);
expect(linkPreviewServiceSpy).toHaveBeenCalledWith('https://example.com/link1');
expect(linkPreviewServiceSpy).toHaveBeenCalledWith('https://example.com/link2');
- expect(component.linkPreviews).toEqual(mockLinkPreviews);
- expect(component.hasError).toBeFalse();
- expect(component.loaded).toBeTrue();
- expect(component.showLoadingsProgress).toBeFalse();
+ expect(component.linkPreviews()).toEqual(mockLinkPreviews);
+ expect(component.hasError()).toBeFalse();
+ expect(component.loaded()).toBeTrue();
+ expect(component.showLoadingsProgress()).toBeFalse();
});
it('should update existing link preview if it already exists', () => {
- component.data = 'Check out these links: https://example.com/link1';
+ fixture.componentRef.setInput('data', 'Check out these links: https://example.com/link1');
const links: Link[] = [{ type: '', value: '', href: 'https://example.com/link1' }];
const existingLinkPreview: LinkPreview = {
url: 'https://example.com/link1',
@@ -77,14 +77,14 @@ describe('LinkPreviewContainerComponent', () => {
const linkifyServiceSpy = jest.spyOn(linkifyService, 'find').mockReturnValue(links);
const linkPreviewServiceSpy = jest.spyOn(linkPreviewService, 'fetchLink').mockReturnValueOnce(of(newLinkPreview));
- component.linkPreviews.push(existingLinkPreview);
+ component.linkPreviews().push(existingLinkPreview);
component.ngOnInit();
- expect(linkifyServiceSpy).toHaveBeenCalledWith(component.data);
+ expect(linkifyServiceSpy).toHaveBeenCalledWith(component.data());
expect(linkPreviewServiceSpy).toHaveBeenCalledOnce();
expect(linkPreviewServiceSpy).toHaveBeenCalledWith('https://example.com/link1');
- expect(component.linkPreviews).toHaveLength(1);
- expect(component.linkPreviews[0]).toEqual(newLinkPreview);
+ expect(component.linkPreviews()).toHaveLength(1);
+ expect(component.linkPreviews()[0]).toEqual(newLinkPreview);
});
});