Skip to content

Commit

Permalink
Merged in DSC-629 (pull request DSpace#584)
Browse files Browse the repository at this point in the history
DSC-629

Approved-by: Giuseppe Digilio
  • Loading branch information
Andrea Barbasso authored and atarix83 committed Apr 20, 2023
2 parents 65019fd + d063d18 commit f0c3921
Show file tree
Hide file tree
Showing 22 changed files with 592 additions and 213 deletions.
51 changes: 50 additions & 1 deletion src/app/core/data/bitstream-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,56 @@ export class BitstreamDataService extends IdentifiableDataService<Bitstream> imp
uuid: string,
bundlename: string,
metadataFilters: MetadataFilter[],
options?: FindListOptions,
options: FindListOptions = {},
useCachedVersionIfAvailable = true,
reRequestOnStale = true,
...linksToFollow: FollowLinkConfig<Bitstream>[]
): Observable<RemoteData<PaginatedList<Bitstream>>> {
const searchParams = [];
searchParams.push(new RequestParam('uuid', uuid));
searchParams.push(new RequestParam('name', bundlename));

metadataFilters.forEach((entry: MetadataFilter) => {
searchParams.push(new RequestParam('filterMetadata', entry.metadataName));
searchParams.push(new RequestParam('filterMetadataValue', entry.metadataValue));
});

const hrefObs = this.getSearchByHref(
'showableByItem',
{ searchParams },
...linksToFollow
);

return this.findListByHref(
hrefObs,
options,
useCachedVersionIfAvailable,
reRequestOnStale,
...linksToFollow
);
}

/**
* Returns an observable of {@link RemoteData} of a {@link Bitstream} that is not marked
* hidden (that hasn't got the metadata `bitstream.hide` or its value is not true/yes).
* resolve {@link HALLink}s of the object
*
* @param uuid The item UUID to retrieve bitstreams from
* @param bundlename Bundle type of the bitstreams
* @param metadataFilters Array of object we want to filter by
* @param options The {@link FindListOptions} for the request
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
* no valid cached version. Defaults to true
* @param reRequestOnStale Whether or not the request should automatically be re-
* requested after the response becomes stale
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which
* {@link HALLink}s should be automatically resolved
*/
showableByItem(
uuid: string,
bundlename: string,
metadataFilters: MetadataFilter[],
options: FindListOptions,
useCachedVersionIfAvailable = true,
reRequestOnStale = true,
...linksToFollow: FollowLinkConfig<Bitstream>[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,84 +1,10 @@
<div class="{{valueStyle}}">
<ng-container *ngFor="let attachment of (bitstreams$ | async); let last = last;">
<ng-template #tipContent>
<span [innerHTML]="('checksum-tooltip.info.' + attachment.checkSum.checkSumAlgorithm | translate)"></span>
</ng-template>
<div class="row mt-1 mb-2" data-test="attachment-info">
<div class="col-3">
<ds-thumbnail [thumbnail]="attachment.thumbnail | async"></ds-thumbnail>
</div>
<div class="col-5">

<ng-container *ngFor="let attachmentConf of envMetadata">

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

<ng-container *ngIf="attachmentConf.type == AdvancedAttachmentElementType.Metadata">

<p class="text-break m-0" data-test="attachment-name" *ngIf="!attachmentConf.truncatable">
{{attachment.firstMetadataValue(attachmentConf.name)}}
</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>

</ng-container>

<ng-container *ngIf="attachmentConf.type == AdvancedAttachmentElementType.Attribute">
<ng-container *ngIf="attachmentConf.name == 'format' && (getFormat(attachment) | async)">
<strong>
{{ 'cris-layout.advanced-attachment.'+attachmentConf.name | translate }}
</strong>
<p class="word-break m-0">{{getFormat(attachment) | async}}</p>
</ng-container>

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

<ng-container *ngIf="attachmentConf.name == 'checksum' && getChecksum(attachment)">
<ng-container *ngVar="getChecksum(attachment) as checksum">
<strong>
{{ 'cris-layout.advanced-attachment.'+ attachmentConf.name | translate }}
({{checksum.checkSumAlgorithm}}) <i class="far fa-question-circle text-info hint" #hint="ngbTooltip"
container="body"
placement="top"
[ngbTooltip]="tipContent"
triggers="manual"
[autoClose]="false"
(click)="hint.toggle();$event.preventDefault();"></i>
</strong>
<p class="word-break m-0">{{checksum.value}}</p>
</ng-container>
</ng-container>
</ng-container>

</div>
</ng-container>

</div>
<div class="col-4 text-right">
<ds-file-download-button [bitstream]="attachment" [enableRequestACopy]="true" [item]="item">
</ds-file-download-button>
</div>
</div>
<hr *ngIf="!last">
<ds-bitstream-attachment data-test="attachment-info" [attachment]="attachment"></ds-bitstream-attachment>
</ng-container>
<div *ngIf="canViewMore" class="w-100 text-center my-3">
<button class="btn btn-outline-primary" data-test="view-more" (click)="viewMore()">
{{'cris-layout.advanced-attachment.viewMore' | translate}}
</button>
</div>
</div>


Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
.img-file {
max-height: var(--ds-advanced-attachment-image-max-height);
object-fit: var(--ds-advanced-attachment-image-object-fit);
object-position: var(--ds-advanced-attachment-image-object-position);
}

.thumbnail-placeholder {
border: var(--ds-thumbnail-placeholder-border);
color: var(--ds-thumbnail-placeholder-color);
font-weight: var(--ds-advanced-attachment-thumbnail-placeholder-font-weight);
}

.hint {
cursor: pointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,43 +197,6 @@ describe('AdvancedAttachmentComponent', () => {
expect(valueFound.length).toBe(3);
}));

it('should show information properly', () => {
const entries = de.queryAll(By.css('[data-test="attachment-info"]'));
expect(entries.length).toBe(3);
expect(entries[0].query(By.css('[data-test="dc.title"]'))).toBeTruthy();
expect(entries[0].query(By.css('[data-test="dc.description"]'))).toBeTruthy();
expect(entries[0].query(By.css('[data-test="dc.type"]'))).toBeTruthy();
expect(entries[0].query(By.css('[data-test="format"]'))).toBeTruthy();
expect(entries[0].query(By.css('[data-test="size"]'))).toBeTruthy();
expect(entries[0].query(By.css('[data-test="checksum"]'))).toBeTruthy();
});

it('should wrap the title', () => {
const titleElement = de.query(By.css('[data-test="attachment-name"]')).nativeElement;
expect(titleElement.classList).toContain('text-break');
});

describe('and the field has metadata key and value set as value', () => {
beforeEach(() => {
// NOTE: Cannot override providers once components have been compiled, so TestBed needs to be reset
TestBed.resetTestingModule();
TestBed.configureTestingModule(getDefaultTestBedConf());
TestBed.overrideProvider('fieldProvider', { useValue: mockFieldWithMetadata });
fixture = TestBed.createComponent(AdvancedAttachmentComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
let spy = spyOn(component, 'getBitstreamsByItem');
spy.and.returnValue(of(createPaginatedList([attachmentsMock[1]])));
component.item = testItem;
fixture.detectChanges();
});

it('should show main article attachment', () => {
expect(de.query(By.css('[data-test="dc.title"]')).nativeElement.innerHTML).toContain('main.pdf');
});

});

});

describe('when pagination is enabled', () => {
Expand Down Expand Up @@ -308,40 +271,6 @@ describe('AdvancedAttachmentComponent', () => {
expect(valueFound.length).toBe(3);
}));

it('should show information properly', () => {
const entries = de.queryAll(By.css('[data-test="attachment-info"]'));
expect(entries.length).toBe(3);
expect(entries[0].query(By.css('[data-test="dc.title"]'))).toBeFalsy();
expect(entries[0].query(By.css('[data-test="dc.description"]'))).toBeFalsy();
expect(entries[0].query(By.css('[data-test="dc.type"]'))).toBeFalsy();
expect(entries[0].query(By.css('[data-test="format"]'))).toBeFalsy();
expect(entries[0].query(By.css('[data-test="size"]'))).toBeFalsy();
expect(entries[0].query(By.css('[data-test="checksum"]'))).toBeFalsy();
});

describe('and the field has metadata key and value set as value', () => {
beforeEach(() => {
// NOTE: Cannot override providers once components have been compiled, so TestBed needs to be reset
TestBed.resetTestingModule();
TestBed.configureTestingModule(getDefaultTestBedConf());
TestBed.overrideProvider('fieldProvider', { useValue: mockFieldWithMetadata });
fixture = TestBed.createComponent(AdvancedAttachmentComponent);
component = fixture.componentInstance;
component.envMetadata = [];
de = fixture.debugElement;
let spy = spyOn(component, 'getBitstreamsByItem');
spy.and.returnValue(of(createPaginatedList([attachmentsMock[1]])));
component.item = testItem;
fixture.detectChanges();
});

it('should show main article attachment', () => {
expect(de.queryAll(By.css('[data-test="attachment-info"]')).length).toBe(1);
expect(de.query(By.css('[data-test="dc.title"]'))).toBeFalsy();
});

});

});

describe('when pagination is enabled', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ import { BitstreamDataService } from '../../../../../../../core/data/bitstream-d
import { Item } from '../../../../../../../core/shared/item.model';
import { LayoutField } from '../../../../../../../core/layout/models/box.model';
import { AttachmentComponent } from '../attachment/attachment.component';
import { AdvancedAttachmentElementType } from '../../../../../../../../config/advanced-attachment-rendering.config';
import { environment } from '../../../../../../../../environments/environment';
import { FindListOptions } from '../../../../../../../core/data/find-list-options.model';
import { Observable } from 'rxjs';
import { buildPaginatedList, PaginatedList } from '../../../../../../../core/data/paginated-list.model';
import { Bitstream } from '../../../../../../../core/shared/bitstream.model';
import { followLink } from '../../../../../../../shared/utils/follow-link-config.model';
import { getFirstCompletedRemoteData } from '../../../../../../../core/shared/operators';
import { map } from 'rxjs/operators';
import { RemoteData } from '../../../../../../../core/data/remote-data';

@Component({
selector: 'ds-advanced-attachment',
Expand All @@ -30,11 +37,6 @@ export class AdvancedAttachmentComponent extends AttachmentComponent implements
*/
envPagination = environment.advancedAttachmentRendering.pagination;

/**
* Configuration type enum
*/
AdvancedAttachmentElementType = AdvancedAttachmentElementType;

constructor(
@Inject('fieldProvider') public fieldProvider: LayoutField,
@Inject('itemProvider') public itemProvider: Item,
Expand All @@ -45,4 +47,14 @@ export class AdvancedAttachmentComponent extends AttachmentComponent implements
super(fieldProvider, itemProvider, renderingSubTypeProvider, bitstreamDataService, translateService);
}

getBitstreamsByItem(options?: FindListOptions): Observable<PaginatedList<Bitstream>> {
return this.bitstreamDataService
.showableByItem(this.item.uuid, this.field.bitstream.bundle, this.getMetadataFilters(), options, false, false, followLink('thumbnail'))
.pipe(
getFirstCompletedRemoteData(),
map((response: RemoteData<PaginatedList<Bitstream>>) => {
return response.hasSucceeded ? response.payload : buildPaginatedList(null, []);
})
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ng-template #attachmentValue dsCrisLayoutLoader></ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AttachmentRenderComponent } from './attachment-render.component';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
AuthorizationDataService
} from '../../../../../../../../../core/data/feature-authorization/authorization-data.service';
import { AuthorizationDataServiceStub } from '../../../../../../../../../shared/testing/authorization-service.stub';

describe('AttachmentRenderComponent', () => {
let component: AttachmentRenderComponent;
let fixture: ComponentFixture<AttachmentRenderComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AttachmentRenderComponent ],
providers: [
{provide: AuthorizationDataService, useClass: AuthorizationDataServiceStub}
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(AttachmentRenderComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading

0 comments on commit f0c3921

Please sign in to comment.