Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 10 additions & 1 deletion src/app/core/data/access-status-data.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { Injectable } from '@angular/core';

Check failure on line 1 in src/app/core/data/access-status-data.service.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!

Check failure on line 1 in src/app/core/data/access-status-data.service.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/app/core/data/access-status-data.service.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/app/core/data/access-status-data.service.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!
import { Observable } from 'rxjs';
import { AccessStatusObject } from 'src/app/shared/object-collection/shared/badges/access-status-badge/access-status.model';

import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Bitstream } from '../shared/bitstream.model';
import { Item } from '../shared/item.model';
import { BaseDataService } from './base/base-data.service';
import { RemoteData } from './remote-data';
import { RequestService } from './request.service';

/**
* Data service responsible for retrieving the access status of Items
* Data service responsible for retrieving the access status of Items and Bitstreams
*/
@Injectable({ providedIn: 'root' })
export class AccessStatusDataService extends BaseDataService<AccessStatusObject> {
Expand All @@ -32,4 +33,12 @@
findAccessStatusFor(item: Item): Observable<RemoteData<AccessStatusObject>> {
return this.findByHref(item._links.accessStatus.href);
}

/**
* Returns {@link RemoteData} of {@link AccessStatusObject} that is the access status of the given bitstream
* @param bitstream Bitstream we want the access status of
*/
findAccessStatusForBitstream(bitstream: Bitstream): Observable<RemoteData<AccessStatusObject>> {
return this.findByHref(bitstream._links.accessStatus.href);
}
}
10 changes: 10 additions & 0 deletions src/app/core/shared/bitstream.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {

Check failure on line 1 in src/app/core/shared/bitstream.model.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!

Check failure on line 1 in src/app/core/shared/bitstream.model.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/app/core/shared/bitstream.model.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/app/core/shared/bitstream.model.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!
autoserialize,
deserialize,
inheritSerialization,
Expand All @@ -10,6 +10,8 @@
typedObject,
} from '../cache/builders/build-decorators';
import { RemoteData } from '../data/remote-data';
import { AccessStatusObject } from '../../shared/object-collection/shared/badges/access-status-badge/access-status.model';
import { ACCESS_STATUS } from '../../shared/object-collection/shared/badges/access-status-badge/access-status.resource-type';
import { BITSTREAM } from './bitstream.resource-type';
import { BitstreamFormat } from './bitstream-format.model';
import { BITSTREAM_FORMAT } from './bitstream-format.resource-type';
Expand Down Expand Up @@ -52,6 +54,7 @@
format: HALLink;
content: HALLink;
thumbnail: HALLink;
accessStatus: HALLink;
};

/**
Expand All @@ -75,6 +78,13 @@
@link(BUNDLE)
bundle?: Observable<RemoteData<Bundle>>;

/**
* The access status for this Bitstream
* Will be undefined unless the accessStatus {@link HALLink} has been resolved.
*/
@link(ACCESS_STATUS, false, 'accessStatus')
accessStatus?: Observable<RemoteData<AccessStatusObject>>;

getParentLinkKey(): keyof this['_links'] {
return 'format';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h3 class="h5 simple-view-element-header">{{"item.page.filesection.original.bund
</dl>
</div>
<div class="col-2">
<ds-file-download-link [bitstream]="file" [item]="item">
<ds-file-download-link [bitstream]="file" [item]="item" [showAccessStatusBadge]="true">
{{"item.page.filesection.download" | translate}}
</ds-file-download-link>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<ng-container *ngVar="(bitstreams$ | async) as bitstreams">
<ds-metadata-field-wrapper *ngIf="bitstreams?.length > 0" [label]="label | translate">
<div class="file-section">
<ds-file-download-link *ngFor="let file of bitstreams; let last=last;" [bitstream]="file" [item]="item">
<ds-file-download-link *ngFor="let file of bitstreams; let last=last;" [bitstream]="file" [item]="item" [showAccessStatusBadge]="true">
<span>
<span *ngIf="primaryBitsreamId === file.id" class="badge badge-primary">{{ 'item.page.bitstreams.primary' | translate }}</span>
{{ dsoNameService.getName(file) }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
@if (showAccessStatusBadge) {
<ds-access-status-badge [object]="bitstream"></ds-access-status-badge>
}
<a [routerLink]="(bitstreamPath$| async)?.routerLink" class="dont-break-out"
[queryParams]="(bitstreamPath$| async)?.queryParams"
[target]="isBlank ? '_blank': '_self'"
[ngClass]="cssClasses"
[attr.aria-label]="('file-download-link.download' | translate) + dsoNameService.getName(bitstream)"
role="link"
tabindex="0">
<span role="img" *ngIf="(canDownload$ |async) !== true" [attr.aria-label]="'file-download-link.restricted' | translate" class="pr-1"><i class="fas fa-lock"></i></span>
<span role="img" *ngIf="(canDownload$ |async) !== true" [attr.aria-label]="'file-download-link.restricted' | translate" class="pl-1"><i class="fas fa-lock"></i></span>
Comment thread
milanmajchrak marked this conversation as resolved.
<ng-container *ngTemplateOutlet="content"></ng-container>
</a>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ import {
hasValue,
isNotEmpty,
} from '../empty.util';
import { ThemedAccessStatusBadgeComponent } from '../object-collection/shared/badges/access-status-badge/themed-access-status-badge.component';

@Component({
selector: 'ds-base-file-download-link',
templateUrl: './file-download-link.component.html',
styleUrls: ['./file-download-link.component.scss'],
standalone: true,
imports: [RouterLink, NgClass, NgIf, NgTemplateOutlet, AsyncPipe, TranslateModule],
imports: [RouterLink, NgClass, NgIf, NgTemplateOutlet, AsyncPipe, TranslateModule, ThemedAccessStatusBadgeComponent],
})
/**
* Component displaying a download link
Expand Down Expand Up @@ -65,6 +66,11 @@ export class FileDownloadLinkComponent implements OnInit {

@Input() enableRequestACopy = true;

/**
* A boolean indicating whether the access status badge is displayed
*/
@Input() showAccessStatusBadge = true;

Comment thread
milanmajchrak marked this conversation as resolved.
bitstreamPath$: Observable<{
routerLink: string,
queryParams: any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ export class ThemedFileDownloadLinkComponent extends ThemedComponent<FileDownloa

@Input() enableRequestACopy: boolean;

protected inAndOutputNames: (keyof FileDownloadLinkComponent & keyof this)[] = ['bitstream', 'item', 'cssClasses', 'isBlank', 'enableRequestACopy'];
@Input() showAccessStatusBadge: boolean;

protected inAndOutputNames: (keyof FileDownloadLinkComponent & keyof this)[] = ['bitstream', 'item', 'cssClasses', 'isBlank', 'enableRequestACopy', 'showAccessStatusBadge'];

protected getComponentName(): string {
return 'FileDownloadLinkComponent';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<ng-container *ngIf="showAccessStatus">
<span *ngIf="accessStatus$ | async as accessStatus">
<span [class]="'badge badge-secondary access-status-list-element-badge ' + accessStatusClass">
@if (showAccessStatus) {
@if ((accessStatus$ | async); as status) {
<span [class]="'badge dont-break-out access-status-list-element-badge ' + accessStatusClass">
Comment thread
milanmajchrak marked this conversation as resolved.
Outdated
<span class="sr-only">{{ 'listelement.badge.access-status' | translate }}</span>
{{ accessStatus | translate }}
{{ status | translate: { date: (embargoDate$ | async) } }}
<span class="sr-only">, </span>
</span>
</span>
</ng-container>
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
span {
white-space: normal;
}

:host {
::ng-deep .access-status-list-element-badge {
margin-right: 0.35rem;
}

// Embargo — DataShare blue with white text
::ng-deep .access-status-embargo-listelement-badge,
::ng-deep .embargo-listelement-badge {
background-color: #004f71 !important;
color: #fff !important;
}

// Open access — DataShare success green
::ng-deep .access-status-open-access-listelement-badge {
background-color: #5cb85c !important;
color: #fff !important;
}

// Restricted — DataShare darker blue
::ng-deep .access-status-restricted-listelement-badge {
background-color: #002b3e !important;
color: #fff !important;
}

// Metadata only — DataShare muted
::ng-deep .access-status-metadata-only-listelement-badge {
background-color: #495057 !important;
color: #fff !important;
Comment thread
milanmajchrak marked this conversation as resolved.
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { environment } from 'src/environments/environment';

import { AccessStatusDataService } from '../../../../../core/data/access-status-data.service';
import { LinkService } from '../../../../../core/cache/builders/link.service';
import { Item } from '../../../../../core/shared/item.model';
import { createSuccessfulRemoteDataObject$ } from '../../../../remote-data.utils';
import { TruncatePipe } from '../../../../utils/truncate.pipe';
Expand All @@ -25,7 +25,7 @@ describe('ItemAccessStatusBadgeComponent', () => {
let embargoStatus: AccessStatusObject;
let restrictedStatus: AccessStatusObject;
Comment thread
milanmajchrak marked this conversation as resolved.

let accessStatusDataService: AccessStatusDataService;
let linkService: LinkService;

let item: Item;

Expand All @@ -50,13 +50,14 @@ describe('ItemAccessStatusBadgeComponent', () => {
status: 'restricted',
});

accessStatusDataService = jasmine.createSpyObj('accessStatusDataService', {
findAccessStatusFor: createSuccessfulRemoteDataObject$(unknownStatus),
linkService = jasmine.createSpyObj('linkService', {
resolveLink: {},
});

item = Object.assign(new Item(), {
uuid: 'item-uuid',
type: 'item',
accessStatus: createSuccessfulRemoteDataObject$(unknownStatus),
});
}

Expand All @@ -65,7 +66,7 @@ describe('ItemAccessStatusBadgeComponent', () => {
imports: [TranslateModule.forRoot(), AccessStatusBadgeComponent, TruncatePipe],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: AccessStatusDataService, useValue: accessStatusDataService },
{ provide: LinkService, useValue: linkService },
],
}).compileComponents();
}
Expand Down Expand Up @@ -113,7 +114,7 @@ describe('ItemAccessStatusBadgeComponent', () => {
describe('When the findAccessStatusFor method returns metadata.only', () => {
beforeEach(waitForAsync(() => {
init();
(accessStatusDataService.findAccessStatusFor as jasmine.Spy).and.returnValue(createSuccessfulRemoteDataObject$(metadataOnlyStatus));
item.accessStatus = createSuccessfulRemoteDataObject$(metadataOnlyStatus);
initTestBed();
}));
beforeEach(() => {
Expand All @@ -127,7 +128,7 @@ describe('ItemAccessStatusBadgeComponent', () => {
describe('When the findAccessStatusFor method returns open.access', () => {
beforeEach(waitForAsync(() => {
init();
(accessStatusDataService.findAccessStatusFor as jasmine.Spy).and.returnValue(createSuccessfulRemoteDataObject$(openAccessStatus));
item.accessStatus = createSuccessfulRemoteDataObject$(openAccessStatus);
initTestBed();
}));
beforeEach(() => {
Expand All @@ -141,7 +142,7 @@ describe('ItemAccessStatusBadgeComponent', () => {
describe('When the findAccessStatusFor method returns embargo', () => {
beforeEach(waitForAsync(() => {
init();
(accessStatusDataService.findAccessStatusFor as jasmine.Spy).and.returnValue(createSuccessfulRemoteDataObject$(embargoStatus));
item.accessStatus = createSuccessfulRemoteDataObject$(embargoStatus);
initTestBed();
}));
beforeEach(() => {
Expand All @@ -155,7 +156,7 @@ describe('ItemAccessStatusBadgeComponent', () => {
describe('When the findAccessStatusFor method returns restricted', () => {
beforeEach(waitForAsync(() => {
init();
(accessStatusDataService.findAccessStatusFor as jasmine.Spy).and.returnValue(createSuccessfulRemoteDataObject$(restrictedStatus));
item.accessStatus = createSuccessfulRemoteDataObject$(restrictedStatus);
initTestBed();
}));
beforeEach(() => {
Expand Down
Loading
Loading