Skip to content

Commit

Permalink
Merged in task/main-cris/DSC-2052 (pull request DSpace#2578)
Browse files Browse the repository at this point in the history
[DSC-2052] Refactoring bitstream-attachment.component in order to fix rendering issue with functions called inside the template

Approved-by: Francesco Molinaro
  • Loading branch information
atarix83 authored and FrancescoMolinaro committed Nov 27, 2024
2 parents fa5e1c9 + 2dbe9f9 commit e7729fb
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {
Component,
ComponentFactory,
ComponentFactoryResolver,
ComponentRef,
inject,
Injector,
Input,
OnInit,
Expand Down Expand Up @@ -53,12 +52,7 @@ export class AttachmentRenderComponent implements OnInit {
read: ViewContainerRef,
}) attachmentValueViewRef: ViewContainerRef;

constructor(
protected componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector,
) {

}
private injector: Injector = inject(Injector);

ngOnInit(): void {
this.attachmentValueViewRef.clear();
Expand All @@ -68,26 +62,28 @@ export class AttachmentRenderComponent implements OnInit {
/**
* Generate ComponentFactory for attachment rendering
*/
computeComponentFactory(): ComponentFactory<any> {
computeComponentFactory(): GenericConstructor<Component> {
const rendering = this.computeRendering();
const attachmentTypeRenderOptions = getAttachmentTypeRendering(rendering);
const constructor: GenericConstructor<Component> = attachmentTypeRenderOptions?.componentRef;
return constructor ? this.componentFactoryResolver.resolveComponentFactory(constructor) : null;
return attachmentTypeRenderOptions?.componentRef || null;
}

/**
* Generate ComponentRef for attachment rendering
*/
generateComponentRef(): ComponentRef<any> {
let attachentComponentRef: ComponentRef<Component>;
const factory: ComponentFactory<any> = this.computeComponentFactory();
if (factory) {
attachentComponentRef = this.attachmentValueViewRef.createComponent(factory, 0, this.getComponentInjector());
(attachentComponentRef.instance as any).item = this.item;
(attachentComponentRef.instance as any).bitstream = this.bitstream;
(attachentComponentRef.instance as any).tabName = this.tabName;
let attachmentComponentRef: ComponentRef<Component>;
const component: GenericConstructor<Component> = this.computeComponentFactory();
if (component) {
attachmentComponentRef = this.attachmentValueViewRef.createComponent(component, {
index: 0,
injector: this.getComponentInjector(),
});
(attachmentComponentRef.instance as any).item = this.item;
(attachmentComponentRef.instance as any).bitstream = this.bitstream;
(attachmentComponentRef.instance as any).tabName = this.tabName;
}
return attachentComponentRef;
return attachmentComponentRef;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<ng-container *ngIf="attachment">
@if (attachment) {
<div class="d-flex flex-row flex-wrap flex-lg-nowrap card-container mt-1 mb-3 gap-3" data-test="attachment-info">

<div class="order-lg-1 thumbnail-wrapper">
Expand All @@ -7,11 +7,11 @@

<div class="order-lg-3 ml-auto">
<div class="d-flex flex-column align-items-end gap-3">
<ng-container *ngFor="let renderingType of allAttachmentProviders">
@for (renderingType of allAttachmentProviders; track $index) {
<div class="text-nowrap">
<ds-attachment-render [renderingType]="renderingType" [bitstream]="attachment" [item]="item" [tabName]="tabName"></ds-attachment-render>
</div>
</ng-container>
}
<!-- Default download button -->
<div class="text-nowrap">
<ds-attachment-render [renderingType]="AttachmentRenderingType.DOWNLOAD" [bitstream]="attachment" [item]="item" [tabName]="tabName"></ds-attachment-render>
Expand All @@ -20,56 +20,64 @@
</div>

<div class="order-lg-2 w-100 mb-3">
<ng-container *ngFor="let attachmentConf of envMetadata">
@for (attachmentConf of envMetadata; track $index) {
@if (attachment.firstMetadataValue(attachmentConf.name) || attachmentConf.type === AdvancedAttachmentElementType.Attribute) {
<div class="content" [attr.data-test]="attachmentConf.name">
<strong>{{ 'cris-layout.advanced-attachment.' + attachmentConf.name | translate }}</strong>

<div class="content"
[attr.data-test]="attachmentConf.name"
*ngIf="attachment.firstMetadataValue(attachmentConf.name) || attachmentConf.type === AdvancedAttachmentElementType.Attribute"
>
<strong>{{ 'cris-layout.advanced-attachment.'+attachmentConf.name | translate }}</strong>
@if (attachmentConf.type === AdvancedAttachmentElementType.Metadata) {

<ng-container *ngIf="attachmentConf.type === AdvancedAttachmentElementType.Metadata">
@if(!attachmentConf.truncatable && attachmentConf.name === attachmentTypeMetadata) {
<p class="text-break m-0">
{{attachment.firstMetadataValue(attachmentConf.name) | titlecase}}
</p>
}

<p class="text-break m-0" *ngIf="!attachmentConf.truncatable && attachmentConf.name === attachmentTypeMetadata">
{{attachment.firstMetadataValue(attachmentConf.name) | titlecase}}
</p>
@if(!attachmentConf.truncatable && attachmentConf.name !== attachmentTypeMetadata) {
<p class="text-break m-0">
{{attachment.firstMetadataValue(attachmentConf.name)}}
</p>
}

<p class="text-break m-0" *ngIf="!attachmentConf.truncatable && attachmentConf.name !== attachmentTypeMetadata">
{{attachment.firstMetadataValue(attachmentConf.name)}}
</p>
@if (attachmentConf.truncatable) {
<ds-truncatable [id]=" attachment.id">
<ds-truncatable-part [id]="attachment.id" [minLines]="1">
{{attachment.firstMetadataValue(attachmentConf.name)}}
</ds-truncatable-part>
</ds-truncatable>
}
}
@if (attachmentConf.type === AdvancedAttachmentElementType.Attribute) {
@if (attachmentConf.name === 'format') {
@if ((bitstreamFormat$ | async) === null || (bitstreamFormat$ | async) === undefined) {
<p class="text-muted">
{{'cris-layout.advanced-attachment.label.not-present' | translate}}
</p>
} @else {
<p class="word-break m-0">{{(bitstreamFormat$ | async)}}</p>
}
}

<ds-truncatable *ngIf="attachmentConf.truncatable" [id]=" attachment.id">
<ds-truncatable-part [id]="attachment.id" [minLines]="1">
{{attachment.firstMetadataValue(attachmentConf.name)}}
</ds-truncatable-part>
</ds-truncatable>
@if (attachmentConf.name === 'size' && bitstreamSize) {
<p class="word-break m-0">{{bitstreamSize | dsFileSize}}</p>
}

</ng-container>
@if (attachmentConf.name === 'checksum') {
@if (checksumInfo?.value === null || checksumInfo?.value === undefined) {
<p class="text-muted">
{{'cris-layout.advanced-attachment.label.not-present' | translate}}
</p>
} @else {
<p class="word-break m-0">({{checksumInfo.checkSumAlgorithm}}):{{ checksumInfo.value }}</p>
}
}
}

<ng-container *ngIf="attachmentConf.type === AdvancedAttachmentElementType.Attribute">
<ng-container *ngIf="attachmentConf.name === 'format'">
<p *ngIf="(getFormat(attachment) | async) === null || (getFormat(attachment) | async) === undefined" class="text-muted">
{{'cris-layout.advanced-attachment.label.not-present' | translate}}
</p>
<p class="word-break m-0">{{getFormat(attachment) | async}}</p>
</ng-container>

<ng-container *ngIf="attachmentConf.name === 'size'">
<p class="word-break m-0">{{getSize(attachment) | dsFileSize}}</p>
</ng-container>

<ng-container *ngIf="attachmentConf.name === 'checksum'">
<p *ngIf="(getChecksum(attachment)?.value) !== true"class="text-muted">
{{'cris-layout.advanced-attachment.label.not-present' | translate}}
</p>
<p class="word-break m-0">({{getChecksum(attachment).checkSumAlgorithm}}):{{ getChecksum(attachment).value }}</p>
</ng-container>
</ng-container>

</div>
</ng-container>
</div>
}
}

</div>

</div>
</ng-container>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ import {
ComponentFixture,
TestBed,
} from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { TranslateService } from '@ngx-translate/core';
import { provideRouter } from '@angular/router';
import {
TranslateLoader,
TranslateModule,
} from '@ngx-translate/core';

import { BitstreamDataService } from '../../../../../../../../core/data/bitstream-data.service';
import { MockBitstream1 } from '../../../../../../../../shared/mocks/item.mock';
import { TranslateLoaderMock } from '../../../../../../../../shared/mocks/translate-loader.mock';
import { TruncatableComponent } from '../../../../../../../../shared/truncatable/truncatable.component';
import { TruncatablePartComponent } from '../../../../../../../../shared/truncatable/truncatable-part/truncatable-part.component';
import { ThemedThumbnailComponent } from '../../../../../../../../thumbnail/themed-thumbnail.component';
import { BitstreamRenderingModelComponent } from '../../bitstream-rendering-model';
import { AttachmentRenderComponent } from './attachment-render/attachment-render.component';
import { BitstreamAttachmentComponent } from './bitstream-attachment.component';

Expand All @@ -19,14 +25,23 @@ describe('BitstreamAttachmentComponent', () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([]), BitstreamAttachmentComponent],
imports: [
BitstreamAttachmentComponent,
BitstreamRenderingModelComponent,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock,
},
}),
],
providers: [
provideRouter([]),
{ provide: 'fieldProvider', useValue: {} },
{ provide: 'itemProvider', useValue: {} },
{ provide: 'renderingSubTypeProvider', useValue: '' },
{ provide: 'tabNameProvider', useValue: '' },
{ provide: BitstreamDataService, useValue: {} },
{ provide: TranslateService, useValue: {} },
],
schemas: [NO_ERRORS_SCHEMA],
})
Expand All @@ -36,6 +51,7 @@ describe('BitstreamAttachmentComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(BitstreamAttachmentComponent);
component = fixture.componentInstance;
component.attachment = MockBitstream1;
fixture.detectChanges();
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import {
AsyncPipe,
NgFor,
NgIf,
TitleCasePipe,
} from '@angular/common';
import {
Expand All @@ -18,12 +16,16 @@ import {
TranslateModule,
TranslateService,
} from '@ngx-translate/core';
import { Observable } from 'rxjs';

import { AdvancedAttachmentElementType } from '../../../../../../../../../config/advanced-attachment-rendering.config';
import { environment } from '../../../../../../../../../environments/environment';
import { BitstreamDataService } from '../../../../../../../../core/data/bitstream-data.service';
import { LayoutField } from '../../../../../../../../core/layout/models/box.model';
import { Bitstream } from '../../../../../../../../core/shared/bitstream.model';
import {
Bitstream,
ChecksumInfo,
} from '../../../../../../../../core/shared/bitstream.model';
import { Item } from '../../../../../../../../core/shared/item.model';
import { TruncatableComponent } from '../../../../../../../../shared/truncatable/truncatable.component';
import { TruncatablePartComponent } from '../../../../../../../../shared/truncatable/truncatable-part/truncatable-part.component';
Expand All @@ -39,9 +41,7 @@ import { AttachmentRenderingType } from './attachment-type.decorator';
styleUrls: ['./bitstream-attachment.component.scss'],
standalone: true,
imports: [
NgIf,
ThemedThumbnailComponent,
NgFor,
AttachmentRenderComponent,
TruncatableComponent,
TruncatablePartComponent,
Expand All @@ -63,6 +63,9 @@ export class BitstreamAttachmentComponent extends BitstreamRenderingModelCompone
*/
AdvancedAttachmentElementType = AdvancedAttachmentElementType;

/**
* Configuration type enum
*/
AttachmentRenderingType = AttachmentRenderingType;

/**
Expand All @@ -73,11 +76,26 @@ export class BitstreamAttachmentComponent extends BitstreamRenderingModelCompone
/**
* Attachment metadata to be displayed in title case
*/

attachmentTypeMetadata = 'dc.type';

@Input()
attachment: Bitstream;
/**
* Attachment to be displayed
*/
@Input() attachment: Bitstream;

/**
* Format of the bitstream
*/
bitstreamFormat$: Observable<string>;

/**
* Size of the bitstream
*/
bitstreamSize: number;
/**
* Checksum info of the bitstream
*/
checksumInfo: ChecksumInfo;

constructor(
@Inject('fieldProvider') public fieldProvider: LayoutField,
Expand All @@ -94,5 +112,8 @@ export class BitstreamAttachmentComponent extends BitstreamRenderingModelCompone

ngOnInit() {
this.allAttachmentProviders = this.attachment?.allMetadataValues('bitstream.viewer.provider');
this.bitstreamFormat$ = this.getFormat(this.attachment);
this.bitstreamSize = this.getSize(this.attachment);
this.checksumInfo = this.getChecksum(this.attachment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import {
} from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {
map,
take,
} from 'rxjs/operators';

import {
BitstreamDataService,
Expand Down Expand Up @@ -123,6 +126,7 @@ export abstract class BitstreamRenderingModelComponent extends RenderingTypeStru
map((rd: RemoteData<BitstreamFormat>) => {
return rd.payload?.shortDescription;
}),
take(1),
);
}

Expand Down

0 comments on commit e7729fb

Please sign in to comment.