Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
14 changes: 13 additions & 1 deletion src/app/+bitstream-page/bitstream-page.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { find } from 'rxjs/operators';
import { hasValue } from '../shared/empty.util';
import { Bitstream } from '../core/shared/bitstream.model';
import { BitstreamDataService } from '../core/data/bitstream-data.service';
import {followLink, FollowLinkConfig} from '../shared/utils/follow-link-config.model';

/**
* This class represents a resolver that requests a specific bitstream before the route is activated
Expand All @@ -23,9 +24,20 @@ export class BitstreamPageResolver implements Resolve<RemoteData<Bitstream>> {
* or an error if something went wrong
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Bitstream>> {
return this.bitstreamService.findById(route.params.id)
return this.bitstreamService.findById(route.params.id, ...this.followLinks)
.pipe(
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
);
}
/**
* Method that returns the follow links to already resolve
* The self links defined in this list are expected to be requested somewhere in the near future
* Requesting them as embeds will limit the number of requests
*/
get followLinks(): Array<FollowLinkConfig<Bitstream>> {
return [
followLink('bundle', undefined, true, followLink('item')),
followLink('format')
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { RouterTestingModule } from '@angular/router/testing';
import { RemoteData } from '../../core/data/remote-data';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { ActivatedRoute } from '@angular/router';
import {ActivatedRoute, Router} from '@angular/router';
import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
Expand All @@ -22,6 +22,11 @@ import { PageInfo } from '../../core/shared/page-info.model';
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
import { RestResponse } from '../../core/cache/response.models';
import { VarDirective } from '../../shared/utils/var.directive';
import {
createSuccessfulRemoteDataObject$
} from '../../shared/remote-data.utils';
import {RouterStub} from '../../shared/testing/router.stub';
import { getItemEditRoute } from '../../+item-page/item-page-routing-paths';

const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
Expand All @@ -34,6 +39,8 @@ let bitstreamFormatService: BitstreamFormatDataService;
let bitstream: Bitstream;
let selectedFormat: BitstreamFormat;
let allFormats: BitstreamFormat[];
let router: Router;
let routerStub;

describe('EditBitstreamPageComponent', () => {
let comp: EditBitstreamPageComponent;
Expand Down Expand Up @@ -105,7 +112,12 @@ describe('EditBitstreamPageComponent', () => {
format: observableOf(new RemoteData(false, false, true, null, selectedFormat)),
_links: {
self: 'bitstream-selflink'
}
},
bundle: createSuccessfulRemoteDataObject$({
item: createSuccessfulRemoteDataObject$({
uuid: 'some-uuid'
})
})
});
bitstreamService = jasmine.createSpyObj('bitstreamService', {
findById: observableOf(new RemoteData(false, false, true, null, bitstream)),
Expand All @@ -118,6 +130,10 @@ describe('EditBitstreamPageComponent', () => {
findAll: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), allFormats)))
});

const itemPageUrl = `fake-url/some-uuid`;
routerStub = Object.assign(new RouterStub(), {
url: `${itemPageUrl}`
});
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), RouterTestingModule],
declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective],
Expand All @@ -127,6 +143,7 @@ describe('EditBitstreamPageComponent', () => {
{ provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: new RemoteData(false, false, true, null, bitstream) }), snapshot: { queryParams: {} } } },
{ provide: BitstreamDataService, useValue: bitstreamService },
{ provide: BitstreamFormatDataService, useValue: bitstreamFormatService },
{ provide: Router, useValue: routerStub },
ChangeDetectorRef
],
schemas: [NO_ERRORS_SCHEMA]
Expand All @@ -138,6 +155,7 @@ describe('EditBitstreamPageComponent', () => {
fixture = TestBed.createComponent(EditBitstreamPageComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
router = (comp as any).router;
});

describe('on startup', () => {
Expand Down Expand Up @@ -213,4 +231,25 @@ describe('EditBitstreamPageComponent', () => {
});
});
});
describe('when the cancel button is clicked', () => {
it('should call navigateToItemEditBitstreams method', () => {
spyOn(comp, 'navigateToItemEditBitstreams');
comp.onCancel();
expect(comp.navigateToItemEditBitstreams).toHaveBeenCalled();
});
});
describe('when navigateToItemEditBitstreams is called, and the component has an itemId', () => {
it('should redirect to the item edit page on the bitstreams tab with the itemId from the component', () => {
comp.itemId = 'some-uuid1'
comp.navigateToItemEditBitstreams();
expect(routerStub.navigate).toHaveBeenCalledWith([getItemEditRoute('some-uuid1'), 'bitstreams']);
});
});
describe('when navigateToItemEditBitstreams is called, and the component does not have an itemId', () => {
it('should redirect to the item edit page on the bitstreams tab with the itemId from the bundle links ', () => {
comp.itemId = undefined;
comp.navigateToItemEditBitstreams();
expect(routerStub.navigate).toHaveBeenCalledWith([getItemEditRoute('some-uuid'), 'bitstreams']);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { Bitstream } from '../../core/shared/bitstream.model';
import { ActivatedRoute, Router } from '@angular/router';
import { filter, map, switchMap } from 'rxjs/operators';
import { map, mergeMap, switchMap} from 'rxjs/operators';
import { combineLatest as observableCombineLatest, of as observableOf } from 'rxjs';
import { Subscription } from 'rxjs/internal/Subscription';
import {
Expand All @@ -19,7 +19,7 @@ import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-f
import { cloneDeep } from 'lodash';
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
import {
getAllSucceededRemoteData, getAllSucceededRemoteDataPayload,
getAllSucceededRemoteDataPayload,
getFirstSucceededRemoteDataPayload,
getRemoteDataPayload,
getSucceededRemoteData
Expand All @@ -35,8 +35,9 @@ import { Location } from '@angular/common';
import { Observable } from 'rxjs/internal/Observable';
import { RemoteData } from '../../core/data/remote-data';
import { PaginatedList } from '../../core/data/paginated-list';
import { followLink } from '../../shared/utils/follow-link-config.model';
import { getItemEditRoute } from '../../+item-page/item-page-routing-paths';
import {Bundle} from '../../core/shared/bundle.model';
import {Item} from '../../core/shared/item.model';

@Component({
selector: 'ds-edit-bitstream-page',
Expand Down Expand Up @@ -299,12 +300,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {

const bitstream$ = this.bitstreamRD$.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
switchMap((bitstream: Bitstream) => this.bitstreamService.findById(bitstream.id, followLink('format')).pipe(
getAllSucceededRemoteData(),
getRemoteDataPayload(),
filter((bs: Bitstream) => hasValue(bs)))
)
getRemoteDataPayload()
);

const allFormats$ = this.bitstreamFormatsRD$.pipe(
Expand Down Expand Up @@ -501,14 +497,18 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
}

/**
* When the item ID is present, navigate back to the item's edit bitstreams page, otherwise go back to the previous
* page the user came from
* When the item ID is present, navigate back to the item's edit bitstreams page,
* otherwise retrieve the item ID based on the owning bundle's link
*/
navigateToItemEditBitstreams() {
if (hasValue(this.itemId)) {
this.router.navigate([getItemEditRoute(this.itemId), 'bitstreams']);
} else {
this.location.back();
this.bitstream.bundle.pipe(getFirstSucceededRemoteDataPayload(),
mergeMap((bundle: Bundle) => bundle.item.pipe(getFirstSucceededRemoteDataPayload(), map((item: Item) => item.uuid))))
.subscribe((item) => {
this.router.navigate(([getItemEditRoute(item), 'bitstreams']));
});
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/app/core/shared/bitstream.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { BITSTREAM } from './bitstream.resource-type';
import { DSpaceObject } from './dspace-object.model';
import { HALLink } from './hal-link.model';
import { HALResource } from './hal-resource.model';
import {BUNDLE} from './bundle.resource-type';
import {Bundle} from './bundle.model';

@typedObject
@inheritSerialization(DSpaceObject)
Expand Down Expand Up @@ -57,4 +59,10 @@ export class Bitstream extends DSpaceObject implements HALResource {
@link(BITSTREAM_FORMAT, false, 'format')
format?: Observable<RemoteData<BitstreamFormat>>;

/**
* The owning bundle for this Bitstream
* Will be undefined unless the bundle{@link HALLink} has been resolved.
*/
@link(BUNDLE)
bundle?: Observable<RemoteData<Bundle>>;
}
10 changes: 10 additions & 0 deletions src/app/core/shared/bundle.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { RemoteData } from '../data/remote-data';
import { PaginatedList } from '../data/paginated-list';
import { BITSTREAM } from './bitstream.resource-type';
import { Bitstream } from './bitstream.model';
import {ITEM} from './item.resource-type';
import {Item} from './item.model';

@typedObject
@inheritSerialization(DSpaceObject)
Expand All @@ -24,6 +26,7 @@ export class Bundle extends DSpaceObject {
self: HALLink;
primaryBitstream: HALLink;
bitstreams: HALLink;
item: HALLink;
};

/**
Expand All @@ -39,4 +42,11 @@ export class Bundle extends DSpaceObject {
*/
@link(BITSTREAM, true)
bitstreams?: Observable<RemoteData<PaginatedList<Bitstream>>>;

/**
* The owning item for this Bundle
* Will be undefined unless the Item{@link HALLink} has been resolved.
*/
@link(ITEM)
item?: Observable<RemoteData<Item>>;
}