diff --git a/src/app/app-routing-paths.ts b/src/app/app-routing-paths.ts index f5a4414756..74a3f7183e 100644 --- a/src/app/app-routing-paths.ts +++ b/src/app/app-routing-paths.ts @@ -4,7 +4,7 @@ import { Collection } from './core/shared/collection.model'; import { Item } from './core/shared/item.model'; import { getCommunityPageRoute } from './community-page/community-page-routing-paths'; import { getCollectionPageRoute } from './collection-page/collection-page-routing-paths'; -import { getItemPageRoute } from './item-page/item-page-routing-paths'; +import { getItemModuleRoute, getItemPageRoute } from './item-page/item-page-routing-paths'; import { hasValue } from './shared/empty.util'; import { URLCombiner } from './core/url-combiner/url-combiner'; @@ -22,8 +22,9 @@ export function getBitstreamModuleRoute() { export function getBitstreamDownloadRoute(bitstream): string { return new URLCombiner(getBitstreamModuleRoute(), bitstream.uuid, 'download').toString(); } -export function getBitstreamRequestACopyRoute(bitstream): string { - return new URLCombiner(getBitstreamModuleRoute(), bitstream.uuid, 'request-a-copy').toString(); +export function getBitstreamRequestACopyRoute(item, bitstream): string { + const url = new URLCombiner(getItemModuleRoute(), item.uuid, 'request-a-copy').toString(); + return `${url}?bitstream=${bitstream.uuid}`; } export const ADMIN_MODULE_PATH = 'admin'; diff --git a/src/app/bitstream-page/bitstream-page-routing.module.ts b/src/app/bitstream-page/bitstream-page-routing.module.ts index 1027c85b46..f0b6e3c6de 100644 --- a/src/app/bitstream-page/bitstream-page-routing.module.ts +++ b/src/app/bitstream-page/bitstream-page-routing.module.ts @@ -45,14 +45,6 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; bitstream: BitstreamPageResolver }, }, - { - // Resolve angular bitstream download URLs - path: ':id/request-a-copy', - component: BitstreamRequestACopyPageComponent, - resolve: { - bitstream: BitstreamPageResolver - }, - }, { path: EDIT_BITSTREAM_PATH, component: EditBitstreamPageComponent, diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.html b/src/app/item-page/full/field-components/file-section/full-file-section.component.html index c5393055df..33acd6650b 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.html +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.html @@ -33,7 +33,7 @@
- + {{"item.page.filesection.download" | translate}}
@@ -74,7 +74,7 @@
- + {{"item.page.filesection.download" | translate}}
diff --git a/src/app/item-page/item-page-routing.module.ts b/src/app/item-page/item-page-routing.module.ts index f2d0a23935..692783e6ab 100644 --- a/src/app/item-page/item-page-routing.module.ts +++ b/src/app/item-page/item-page-routing.module.ts @@ -12,6 +12,8 @@ import { MenuItemType } from '../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedItemPageComponent } from './simple/themed-item-page.component'; import { ThemedFullItemPageComponent } from './full/themed-full-item-page.component'; +import { BitstreamRequestACopyPageComponent } from '../shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component'; +import { BitstreamPageResolver } from '../bitstream-page/bitstream-page.resolver'; @NgModule({ imports: [ @@ -42,6 +44,10 @@ import { ThemedFullItemPageComponent } from './full/themed-full-item-page.compon path: UPLOAD_BITSTREAM_PATH, component: UploadBitstreamComponent, canActivate: [AuthenticatedGuard] + }, + { + path: ':request-a-copy', + component: BitstreamRequestACopyPageComponent, } ], data: { diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.html b/src/app/item-page/simple/field-components/file-section/file-section.component.html index 0fa5daa012..3d093f83c9 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.html +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.html @@ -1,7 +1,7 @@
- + {{file?.name}} ({{(file?.sizeBytes) | dsFileSize }}) diff --git a/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.html b/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.html index 4ab6963f74..1fae737fdb 100644 --- a/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.html +++ b/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.html @@ -5,8 +5,9 @@ {{'bitstream-request-a-copy.alert.canDownload2'| translate}}
-

{{'bitstream-request-a-copy.intro' | translate}}

-

{{itemName}}

+

{{'bitstream-request-a-copy.intro' | translate}} {{itemName}}

+

{{'bitstream-request-a-copy.intro.bitstream.one' | translate}} {{bitstreamName}}

+

{{'bitstream-request-a-copy.intro.bitstream.all' | translate}}

@@ -45,13 +46,13 @@
{{'bitstream-request-a-copy.allfiles.label' |translate}}
+ id="allfiles-true" formControlName="allfiles" value="true">
+ id="allfiles-false" formControlName="allfiles" value="false" [attr.disabled]="bitstream === undefined ? true : null ">
diff --git a/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.spec.ts b/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.spec.ts index 20df5dfb03..cc44ef8587 100644 --- a/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.spec.ts +++ b/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.spec.ts @@ -21,10 +21,10 @@ import { NotificationsService } from '../notifications/notifications.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../mocks/dso-name.service.mock'; import { Item } from '../../core/shared/item.model'; -import { Bundle } from '../../core/shared/bundle.model'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { ItemRequest } from '../../core/shared/item-request.model'; import { Location } from '@angular/common'; +import { BitstreamDataService } from '../../core/data/bitstream-data.service'; describe('BitstreamRequestACopyPageComponent', () => { @@ -38,6 +38,7 @@ describe('BitstreamRequestACopyPageComponent', () => { let itemRequestDataService; let notificationsService; let location; + let bitstreamDataService; let item: Item; let bitstream: Bitstream; @@ -71,14 +72,8 @@ describe('BitstreamRequestACopyPageComponent', () => { item = Object.assign(new Item(), {uuid: 'item-uuid'}); - const bundle = Object.assign(new Bundle(), { - uuid: 'bundle-uuid', - item: createSuccessfulRemoteDataObject$(item) - }); - bitstream = Object.assign(new Bitstream(), { uuid: 'bitstreamUuid', - bundle: createSuccessfulRemoteDataObject$(bundle), _links: { content: {href: 'bitstream-content-link'}, self: {href: 'bitstream-self-link'}, @@ -87,12 +82,19 @@ describe('BitstreamRequestACopyPageComponent', () => { activatedRoute = { data: observableOf({ - bitstream: createSuccessfulRemoteDataObject( - bitstream + dso: createSuccessfulRemoteDataObject( + item ) + }), + queryParams: observableOf({ + bitstream : bitstream.uuid }) }; + bitstreamDataService = jasmine.createSpyObj('bitstreamDataService', { + findById: createSuccessfulRemoteDataObject$(bitstream) + }); + router = new RouterStub(); } @@ -109,6 +111,7 @@ describe('BitstreamRequestACopyPageComponent', () => { {provide: ItemRequestDataService, useValue: itemRequestDataService}, {provide: NotificationsService, useValue: notificationsService}, {provide: DSONameService, useValue: new DSONameServiceMock()}, + {provide: BitstreamDataService, useValue: bitstreamDataService}, ] }) .compileComponents(); @@ -143,7 +146,7 @@ describe('BitstreamRequestACopyPageComponent', () => { it('show the form with no values filled in based on the user', () => { expect(component.name.value).toEqual(''); expect(component.email.value).toEqual(''); - expect(component.allfiles.value).toEqual('true'); + expect(component.allfiles.value).toEqual('false'); expect(component.message.value).toEqual(''); }); }); @@ -163,8 +166,38 @@ describe('BitstreamRequestACopyPageComponent', () => { fixture.detectChanges(); expect(component.name.value).toEqual(eperson.name); expect(component.email.value).toEqual(eperson.email); + expect(component.allfiles.value).toEqual('false'); + expect(component.message.value).toEqual(''); + }); + }); + describe('when no bitstream was provided', () => { + beforeEach(waitForAsync(() => { + init(); + activatedRoute = { + data: observableOf({ + dso: createSuccessfulRemoteDataObject( + item + ) + }), + queryParams: observableOf({ + }) + }; + initTestbed(); + })); + beforeEach(() => { + fixture = TestBed.createComponent(BitstreamRequestACopyPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should set the all files value to true and disable the false value', () => { + expect(component.name.value).toEqual(''); + expect(component.email.value).toEqual(''); expect(component.allfiles.value).toEqual('true'); expect(component.message.value).toEqual(''); + + const allFilesFalse = fixture.debugElement.query(By.css('#allfiles-false')).nativeElement; + expect(allFilesFalse.getAttribute('disabled')).toBeTruthy(); + }); }); describe('when the user has authorization to download the file', () => { diff --git a/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.ts b/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.ts index 35b56e5434..7697d5fad8 100644 --- a/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.ts +++ b/src/app/shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { map, switchMap, take } from 'rxjs/operators'; +import { filter, map, switchMap, take, tap } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { hasValue, isNotEmpty } from '../empty.util'; import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; @@ -17,9 +17,10 @@ import { ItemRequestDataService } from '../../core/data/item-request-data.servic import { ItemRequest } from '../../core/shared/item-request.model'; import { Item } from '../../core/shared/item.model'; import { NotificationsService } from '../notifications/notifications.service'; -import { getItemPageRoute } from '../../item-page/item-page-routing-paths'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { Location } from '@angular/common'; +import { BitstreamDataService } from '../../core/data/bitstream-data.service'; +import { getItemPageRoute } from '../../item-page/item-page-routing-paths'; @Component({ selector: 'ds-bitstream-request-a-copy-page', @@ -30,15 +31,19 @@ import { Location } from '@angular/common'; */ export class BitstreamRequestACopyPageComponent implements OnInit, OnDestroy { - bitstream$: Observable; + item$: Observable; canDownload$: Observable; private subs: Subscription[] = []; requestCopyForm: FormGroup; - bitstream: Bitstream; + item: Item; itemName: string; + bitstream$: Observable; + bitstream: Bitstream; + bitstreamName: string; + constructor(private location: Location, private translateService: TranslateService, private route: ActivatedRoute, @@ -49,6 +54,7 @@ export class BitstreamRequestACopyPageComponent implements OnInit, OnDestroy { private itemRequestDataService: ItemRequestDataService, private notificationsService: NotificationsService, private dsoNameService: DSONameService, + private bitstreamService: BitstreamDataService, ) { } @@ -66,23 +72,25 @@ export class BitstreamRequestACopyPageComponent implements OnInit, OnDestroy { }); - this.bitstream$ = this.route.data.pipe( - map((data) => data.bitstream), + this.item$ = this.route.data.pipe( + map((data) => data.dso), + getFirstSucceededRemoteDataPayload() + ); + + this.subs.push(this.item$.subscribe((item) => { + this.item = item; + this.itemName = this.dsoNameService.getName(item); + })); + + this.bitstream$ = this.route.queryParams.pipe( + filter((params) => hasValue(params) && hasValue(params.bitstream)), + switchMap((params) => this.bitstreamService.findById(params.bitstream)), getFirstSucceededRemoteDataPayload() ); this.subs.push(this.bitstream$.subscribe((bitstream) => { this.bitstream = bitstream; - })); - - this.subs.push(this.bitstream$.pipe( - switchMap((bitstream) => bitstream.bundle), - getFirstSucceededRemoteDataPayload(), - switchMap((bundle) => bundle.item), - getFirstSucceededRemoteDataPayload(), - ).subscribe((item) => { - this.item = item; - this.itemName = this.dsoNameService.getName(item); + this.bitstreamName = this.dsoNameService.getName(bitstream); })); this.canDownload$ = this.bitstream$.pipe( @@ -124,9 +132,11 @@ export class BitstreamRequestACopyPageComponent implements OnInit, OnDestroy { this.requestCopyForm.patchValue({allfiles: 'true'}); if (hasValue(user)) { this.requestCopyForm.patchValue({name: user.name, email: user.email}); - console.log('ping'); } }); + this.bitstream$.pipe(take(1)).subscribe((bitstream) => { + this.requestCopyForm.patchValue({allfiles: 'false'}); + }); } /** @@ -152,10 +162,10 @@ export class BitstreamRequestACopyPageComponent implements OnInit, OnDestroy { */ onSubmit() { const itemRequest = new ItemRequest(); - if (hasValue(this.item)) { - itemRequest.itemId = this.item.uuid; + if (hasValue(this.bitstream)) { + itemRequest.bitstreamId = this.bitstream.uuid; } - itemRequest.bitstreamId = this.bitstream.uuid; + itemRequest.itemId = this.item.uuid; itemRequest.allfiles = this.allfiles.value; itemRequest.requestEmail = this.email.value; itemRequest.requestName = this.name.value; @@ -190,6 +200,10 @@ export class BitstreamRequestACopyPageComponent implements OnInit, OnDestroy { this.location.back(); } + getItemPath() { + return [getItemPageRoute(this.item)]; + } + /** * Retrieves the link to the bistream download page */ diff --git a/src/app/shared/file-download-link/file-download-link.component.spec.ts b/src/app/shared/file-download-link/file-download-link.component.spec.ts index 80a30e3bdd..cdf4f30837 100644 --- a/src/app/shared/file-download-link/file-download-link.component.spec.ts +++ b/src/app/shared/file-download-link/file-download-link.component.spec.ts @@ -7,6 +7,8 @@ import { getBitstreamModuleRoute } from '../../app-routing-paths'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { cold, getTestScheduler } from 'jasmine-marbles'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; +import { Item } from '../../core/shared/item.model'; +import { getItemModuleRoute } from '../../item-page/item-page-routing-paths'; describe('FileDownloadLinkComponent', () => { let component: FileDownloadLinkComponent; @@ -16,6 +18,7 @@ describe('FileDownloadLinkComponent', () => { let authorizationService: AuthorizationDataService; let bitstream: Bitstream; + let item: Item; function init() { authorizationService = jasmine.createSpyObj('authorizationService', { @@ -27,6 +30,12 @@ describe('FileDownloadLinkComponent', () => { self: {href: 'obj-selflink'} } }); + item = Object.assign(new Item(), { + uuid: 'itemUuid', + _links: { + self: {href: 'obj-selflink'} + } + }); } function initTestbed() { @@ -52,6 +61,7 @@ describe('FileDownloadLinkComponent', () => { fixture = TestBed.createComponent(FileDownloadLinkComponent); component = fixture.componentInstance; component.bitstream = bitstream; + component.item = item; fixture.detectChanges(); }); it('should return the bitstreamPath based on the input bitstream', () => { @@ -83,11 +93,12 @@ describe('FileDownloadLinkComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(FileDownloadLinkComponent); component = fixture.componentInstance; + component.item = item; component.bitstream = bitstream; fixture.detectChanges(); }); it('should return the bitstreamPath based on the input bitstream', () => { - expect(component.bitstreamPath$).toBeObservable(cold('-a', {a: new URLCombiner(getBitstreamModuleRoute(), bitstream.uuid, 'request-a-copy').toString()})); + expect(component.bitstreamPath$).toBeObservable(cold('-a', {a: `${new URLCombiner(getItemModuleRoute(), item.uuid, 'request-a-copy').toString()}?bitstream=${bitstream.uuid}`})); expect(component.canDownload$).toBeObservable(cold('--a', {a: false})); }); @@ -95,7 +106,7 @@ describe('FileDownloadLinkComponent', () => { scheduler.flush(); fixture.detectChanges(); const link = fixture.debugElement.query(By.css('a')).nativeElement; - expect(link.href).toContain(new URLCombiner(getBitstreamModuleRoute(), bitstream.uuid, 'request-a-copy').toString()); + expect(link.href).toContain(`${new URLCombiner(getItemModuleRoute(), item.uuid, 'request-a-copy').toString()}?bitstream=${bitstream.uuid}`); const lock = fixture.debugElement.query(By.css('.fa-lock')).nativeElement; expect(lock).toBeTruthy(); }); @@ -111,6 +122,7 @@ describe('FileDownloadLinkComponent', () => { fixture = TestBed.createComponent(FileDownloadLinkComponent); component = fixture.componentInstance; component.bitstream = bitstream; + component.item = item; fixture.detectChanges(); }); it('should return the bitstreamPath based on the input bitstream', () => { diff --git a/src/app/shared/file-download-link/file-download-link.component.ts b/src/app/shared/file-download-link/file-download-link.component.ts index 2d98c97821..40d871109a 100644 --- a/src/app/shared/file-download-link/file-download-link.component.ts +++ b/src/app/shared/file-download-link/file-download-link.component.ts @@ -3,9 +3,10 @@ import { Bitstream } from '../../core/shared/bitstream.model'; import { getBitstreamDownloadRoute, getBitstreamRequestACopyRoute } from '../../app-routing-paths'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; -import { isNotEmpty } from '../empty.util'; +import { hasValue, isNotEmpty } from '../empty.util'; import { map } from 'rxjs/operators'; import { of as observableOf, combineLatest as observableCombineLatest, Observable } from 'rxjs'; +import { Item } from '../../core/shared/item.model'; @Component({ selector: 'ds-file-download-link', @@ -24,6 +25,8 @@ export class FileDownloadLinkComponent implements OnInit { */ @Input() bitstream: Bitstream; + @Input() item: Item; + /** * Additional css classes to apply to link */ @@ -59,8 +62,8 @@ export class FileDownloadLinkComponent implements OnInit { } getBitstreamPath(canDownload: boolean, canRequestACopy: boolean) { - if (!canDownload && canRequestACopy) { - return getBitstreamRequestACopyRoute(this.bitstream); + if (!canDownload && canRequestACopy && hasValue(this.item)) { + return getBitstreamRequestACopyRoute(this.item, this.bitstream); } return getBitstreamDownloadRoute(this.bitstream); } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 2448570ab4..d83ef56a5a 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -594,7 +594,10 @@ "bitstream-request-a-copy.header": "Request a copy of the file", - "bitstream-request-a-copy.intro": "Enter the following information to request a copy", + "bitstream-request-a-copy.intro": "Enter the following information to request a copy for the following item: ", + + "bitstream-request-a-copy.intro.bitstream.one": "Requesting the following file: ", + "bitstream-request-a-copy.intro.bitstream.all": "Requesting all files. ", "bitstream-request-a-copy.name.label": "Name *",