Skip to content

Commit 994c9b3

Browse files
authored
Merge pull request DSpace#1694 from atmire/w2p-92282_Fix-missing-auth-tokens-when-retrieving-Bitstreams
Support restricted thumbnails
2 parents 9c93a8a + 7a89f41 commit 994c9b3

13 files changed

Lines changed: 418 additions & 95 deletions

src/app/admin/admin-search-page/admin-search-results/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ import { By } from '@angular/platform-browser';
1414
import { RouterTestingModule } from '@angular/router/testing';
1515
import { getCollectionEditRoute } from '../../../../../collection-page/collection-page-routing-paths';
1616
import { LinkService } from '../../../../../core/cache/builders/link.service';
17+
import { AuthService } from '../../../../../core/auth/auth.service';
18+
import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub';
19+
import { FileService } from '../../../../../core/shared/file.service';
20+
import { FileServiceStub } from '../../../../../shared/testing/file-service.stub';
21+
import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service';
22+
import { AuthorizationDataServiceStub } from '../../../../../shared/testing/authorization-service.stub';
23+
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
24+
import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock';
1725

1826
describe('CollectionAdminSearchResultGridElementComponent', () => {
1927
let component: CollectionAdminSearchResultGridElementComponent;
@@ -45,7 +53,11 @@ describe('CollectionAdminSearchResultGridElementComponent', () => {
4553
providers: [
4654
{ provide: TruncatableService, useValue: mockTruncatableService },
4755
{ provide: BitstreamDataService, useValue: {} },
48-
{ provide: LinkService, useValue: linkService }
56+
{ provide: LinkService, useValue: linkService },
57+
{ provide: AuthService, useClass: AuthServiceStub },
58+
{ provide: FileService, useClass: FileServiceStub },
59+
{ provide: AuthorizationDataService, useClass: AuthorizationDataServiceStub },
60+
{ provide: ThemeService, useValue: getMockThemeService() },
4961
]
5062
})
5163
.compileComponents();

src/app/admin/admin-search-page/admin-search-results/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ import { CommunitySearchResult } from '../../../../../shared/object-collection/s
1616
import { Community } from '../../../../../core/shared/community.model';
1717
import { getCommunityEditRoute } from '../../../../../community-page/community-page-routing-paths';
1818
import { LinkService } from '../../../../../core/cache/builders/link.service';
19+
import { AuthService } from '../../../../../core/auth/auth.service';
20+
import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub';
21+
import { FileService } from '../../../../../core/shared/file.service';
22+
import { FileServiceStub } from '../../../../../shared/testing/file-service.stub';
23+
import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service';
24+
import { AuthorizationDataServiceStub } from '../../../../../shared/testing/authorization-service.stub';
25+
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
26+
import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock';
1927

2028
describe('CommunityAdminSearchResultGridElementComponent', () => {
2129
let component: CommunityAdminSearchResultGridElementComponent;
@@ -47,7 +55,11 @@ describe('CommunityAdminSearchResultGridElementComponent', () => {
4755
providers: [
4856
{ provide: TruncatableService, useValue: mockTruncatableService },
4957
{ provide: BitstreamDataService, useValue: {} },
50-
{ provide: LinkService, useValue: linkService }
58+
{ provide: LinkService, useValue: linkService },
59+
{ provide: AuthService, useClass: AuthServiceStub },
60+
{ provide: FileService, useClass: FileServiceStub },
61+
{ provide: AuthorizationDataService, useClass: AuthorizationDataServiceStub },
62+
{ provide: ThemeService, useValue: getMockThemeService() },
5163
],
5264
schemas: [NO_ERRORS_SCHEMA]
5365
})

src/app/admin/admin-search-page/admin-search-results/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import { getMockThemeService } from '../../../../../shared/mocks/theme-service.m
2020
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
2121
import { AccessStatusDataService } from '../../../../../core/data/access-status-data.service';
2222
import { AccessStatusObject } from '../../../../../shared/object-list/access-status-badge/access-status.model';
23+
import { AuthService } from '../../../../../core/auth/auth.service';
24+
import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub';
25+
import { FileService } from '../../../../../core/shared/file.service';
26+
import { FileServiceStub } from '../../../../../shared/testing/file-service.stub';
27+
import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service';
28+
import { AuthorizationDataServiceStub } from '../../../../../shared/testing/authorization-service.stub';
2329

2430
describe('ItemAdminSearchResultGridElementComponent', () => {
2531
let component: ItemAdminSearchResultGridElementComponent;
@@ -64,6 +70,9 @@ describe('ItemAdminSearchResultGridElementComponent', () => {
6470
{ provide: BitstreamDataService, useValue: mockBitstreamDataService },
6571
{ provide: ThemeService, useValue: mockThemeService },
6672
{ provide: AccessStatusDataService, useValue: mockAccessStatusDataService },
73+
{ provide: AuthService, useClass: AuthServiceStub },
74+
{ provide: FileService, useClass: FileServiceStub },
75+
{ provide: AuthorizationDataService, useClass: AuthorizationDataServiceStub },
6776
],
6877
schemas: [NO_ERRORS_SCHEMA]
6978
})

src/app/shared/loading/loading.component.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div>
1+
<div *ngIf="!spinner">
22
<label *ngIf="showMessage && message">{{ message }}</label>
33
<div class="loader">
44
<span class="l-1"></span>
@@ -13,3 +13,6 @@
1313
<span class="l-10"></span>
1414
</div>
1515
</div>
16+
<div *ngIf='spinner' class="spinner spinner-border" role="status">
17+
<span class="sr-only">{{ message }}</span>
18+
</div>

src/app/shared/loading/loading.component.scss

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
}
44

55
span {
6-
display: block;
6+
display: block;
77
margin: 0 auto;
88
}
99

@@ -13,11 +13,11 @@ span[class*="l-"] {
1313
background: #000;
1414
display: inline-block;
1515
margin: 12px 2px;
16-
16+
1717
border-radius: 100%;
1818
-webkit-border-radius: 100%;
1919
-moz-border-radius: 100%;
20-
20+
2121
-webkit-animation: loader 2s infinite;
2222
-webkit-animation-timing-function: cubic-bezier(0.030, 0.615, 0.995, 0.415);
2323
-webkit-animation-fill-mode: both;
@@ -71,3 +71,7 @@ span.l-10 {-webkit-animation-delay: 0s;animation-delay: 0s;-ms-animation-delay:
7171
50% {-ms-transform: translateX(30px); opacity: 0;}
7272
100% {opacity: 0;}
7373
}
74+
75+
.spinner {
76+
color: var(--bs-gray-600);
77+
}

src/app/shared/loading/loading.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export class LoadingComponent implements OnDestroy, OnInit {
1515
@Input() message: string;
1616
@Input() showMessage = true;
1717

18+
/**
19+
* Show a more compact spinner animation instead of the default one
20+
*/
21+
@Input() spinner = false;
22+
1823
private subscription: Subscription;
1924

2025
constructor(private translate: TranslateService) {

src/app/shared/loading/themed-loading.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ export class ThemedLoadingComponent extends ThemedComponent<LoadingComponent> {
1515

1616
@Input() message: string;
1717
@Input() showMessage = true;
18+
@Input() spinner = false;
1819

19-
protected inAndOutputNames: (keyof LoadingComponent & keyof this)[] = ['message', 'showMessage'];
20+
protected inAndOutputNames: (keyof LoadingComponent & keyof this)[] = ['message', 'showMessage', 'spinner'];
2021

2122
constructor(
2223
protected resolver: ComponentFactoryResolver,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Observable, of as observableOf } from 'rxjs';
2+
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
3+
4+
export class AuthorizationDataServiceStub {
5+
isAuthorized(featureId?: FeatureID, objectUrl?: string, ePersonUuid?: string): Observable<boolean> {
6+
return observableOf(false);
7+
}
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { of as observableOf } from 'rxjs';
2+
3+
export class FileServiceStub {
4+
retrieveFileDownloadLink() {
5+
return observableOf(null);
6+
}
7+
}
Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1-
<div class="thumbnail" [class.limit-width]="limitWidth">
2-
<ds-themed-loading *ngIf="isLoading; else showThumbnail" class="thumbnail-content" [showMessage]="false">
3-
text-content
4-
</ds-themed-loading>
5-
<ng-template #showThumbnail>
6-
<img *ngIf="src !== null" class="thumbnail-content img-fluid"
7-
[src]="src | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()">
8-
<div *ngIf="src === null" class="thumbnail-content outer">
1+
<div class="thumbnail" [class.limit-width]="limitWidth" *ngVar="(isLoading$ | async) as isLoading">
2+
<div *ngIf="isLoading" class="thumbnail-content outer">
3+
<div class="inner">
4+
<div class="centered">
5+
<ds-themed-loading [spinner]="true"></ds-themed-loading>
6+
</div>
7+
</div>
8+
</div>
9+
<ng-container *ngVar="(src$ | async) as src">
10+
<!-- don't use *ngIf="!isLoading" so the thumbnail can load in while the animation is playing -->
11+
<img *ngIf="src !== null" class="thumbnail-content img-fluid" [ngClass]="{'d-none': isLoading}"
12+
[src]="src | dsSafeUrl" [alt]="alt | translate" (error)="errorHandler()" (load)="successHandler()">
13+
<div *ngIf="src === null && !isLoading" class="thumbnail-content outer">
914
<div class="inner">
10-
<div class="thumbnail-placeholder w-100 h-100 lead">{{ placeholder | translate }}</div>
15+
<div class="thumbnail-placeholder centered lead">
16+
{{ placeholder | translate }}
17+
</div>
1118
</div>
1219
</div>
13-
</ng-template>
20+
</ng-container>
1421
</div>

0 commit comments

Comments
 (0)