mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge branch 'main' into #0-fix-thumbnail
This commit is contained in:
@@ -18,6 +18,7 @@ import { WorkflowItemSearchResult } from '../../../../../shared/object-collectio
|
|||||||
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
|
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils';
|
||||||
import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock';
|
import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
describe('WorkflowItemAdminWorkflowGridElementComponent', () => {
|
describe('WorkflowItemAdminWorkflowGridElementComponent', () => {
|
||||||
let component: WorkflowItemSearchResultAdminWorkflowGridElementComponent;
|
let component: WorkflowItemSearchResultAdminWorkflowGridElementComponent;
|
||||||
@@ -50,7 +51,9 @@ describe('WorkflowItemAdminWorkflowGridElementComponent', () => {
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: LinkService, useValue: linkService },
|
{ provide: LinkService, useValue: linkService },
|
||||||
{ provide: TruncatableService, useValue: {} },
|
{ provide: TruncatableService, useValue: {
|
||||||
|
isCollapsed: () => observableOf(true),
|
||||||
|
} },
|
||||||
{ provide: BitstreamDataService, useValue: {} },
|
{ provide: BitstreamDataService, useValue: {} },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
@@ -6,6 +6,7 @@ import { find } from 'rxjs/operators';
|
|||||||
import { hasValue } from '../shared/empty.util';
|
import { hasValue } from '../shared/empty.util';
|
||||||
import { Bitstream } from '../core/shared/bitstream.model';
|
import { Bitstream } from '../core/shared/bitstream.model';
|
||||||
import { BitstreamDataService } from '../core/data/bitstream-data.service';
|
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
|
* This class represents a resolver that requests a specific bitstream before the route is activated
|
||||||
@@ -23,9 +24,20 @@ export class BitstreamPageResolver implements Resolve<RemoteData<Bitstream>> {
|
|||||||
* or an error if something went wrong
|
* or an error if something went wrong
|
||||||
*/
|
*/
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Bitstream>> {
|
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(
|
.pipe(
|
||||||
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
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')
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
|||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
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 { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
||||||
@@ -22,6 +22,11 @@ import { PageInfo } from '../../core/shared/page-info.model';
|
|||||||
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
|
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
|
||||||
import { RestResponse } from '../../core/cache/response.models';
|
import { RestResponse } from '../../core/cache/response.models';
|
||||||
import { VarDirective } from '../../shared/utils/var.directive';
|
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 infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
|
||||||
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
||||||
@@ -34,6 +39,8 @@ let bitstreamFormatService: BitstreamFormatDataService;
|
|||||||
let bitstream: Bitstream;
|
let bitstream: Bitstream;
|
||||||
let selectedFormat: BitstreamFormat;
|
let selectedFormat: BitstreamFormat;
|
||||||
let allFormats: BitstreamFormat[];
|
let allFormats: BitstreamFormat[];
|
||||||
|
let router: Router;
|
||||||
|
let routerStub;
|
||||||
|
|
||||||
describe('EditBitstreamPageComponent', () => {
|
describe('EditBitstreamPageComponent', () => {
|
||||||
let comp: EditBitstreamPageComponent;
|
let comp: EditBitstreamPageComponent;
|
||||||
@@ -105,7 +112,12 @@ describe('EditBitstreamPageComponent', () => {
|
|||||||
format: observableOf(new RemoteData(false, false, true, null, selectedFormat)),
|
format: observableOf(new RemoteData(false, false, true, null, selectedFormat)),
|
||||||
_links: {
|
_links: {
|
||||||
self: 'bitstream-selflink'
|
self: 'bitstream-selflink'
|
||||||
}
|
},
|
||||||
|
bundle: createSuccessfulRemoteDataObject$({
|
||||||
|
item: createSuccessfulRemoteDataObject$({
|
||||||
|
uuid: 'some-uuid'
|
||||||
|
})
|
||||||
|
})
|
||||||
});
|
});
|
||||||
bitstreamService = jasmine.createSpyObj('bitstreamService', {
|
bitstreamService = jasmine.createSpyObj('bitstreamService', {
|
||||||
findById: observableOf(new RemoteData(false, false, true, null, bitstream)),
|
findById: observableOf(new RemoteData(false, false, true, null, bitstream)),
|
||||||
@@ -118,6 +130,10 @@ describe('EditBitstreamPageComponent', () => {
|
|||||||
findAll: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), allFormats)))
|
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({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), RouterTestingModule],
|
imports: [TranslateModule.forRoot(), RouterTestingModule],
|
||||||
declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective],
|
declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective],
|
||||||
@@ -127,6 +143,7 @@ describe('EditBitstreamPageComponent', () => {
|
|||||||
{ provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: new RemoteData(false, false, true, null, bitstream) }), snapshot: { queryParams: {} } } },
|
{ provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: new RemoteData(false, false, true, null, bitstream) }), snapshot: { queryParams: {} } } },
|
||||||
{ provide: BitstreamDataService, useValue: bitstreamService },
|
{ provide: BitstreamDataService, useValue: bitstreamService },
|
||||||
{ provide: BitstreamFormatDataService, useValue: bitstreamFormatService },
|
{ provide: BitstreamFormatDataService, useValue: bitstreamFormatService },
|
||||||
|
{ provide: Router, useValue: routerStub },
|
||||||
ChangeDetectorRef
|
ChangeDetectorRef
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
@@ -138,6 +155,7 @@ describe('EditBitstreamPageComponent', () => {
|
|||||||
fixture = TestBed.createComponent(EditBitstreamPageComponent);
|
fixture = TestBed.createComponent(EditBitstreamPageComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
router = (comp as any).router;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('on startup', () => {
|
describe('on startup', () => {
|
||||||
@@ -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']);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Bitstream } from '../../core/shared/bitstream.model';
|
import { Bitstream } from '../../core/shared/bitstream.model';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
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 { combineLatest as observableCombineLatest, of as observableOf } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs/internal/Subscription';
|
import { Subscription } from 'rxjs/internal/Subscription';
|
||||||
import {
|
import {
|
||||||
@@ -19,7 +19,7 @@ import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-f
|
|||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
||||||
import {
|
import {
|
||||||
getAllSucceededRemoteData, getAllSucceededRemoteDataPayload,
|
getAllSucceededRemoteDataPayload,
|
||||||
getFirstSucceededRemoteDataPayload,
|
getFirstSucceededRemoteDataPayload,
|
||||||
getRemoteDataPayload,
|
getRemoteDataPayload,
|
||||||
getSucceededRemoteData
|
getSucceededRemoteData
|
||||||
@@ -35,8 +35,9 @@ import { Location } from '@angular/common';
|
|||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
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 { getItemEditRoute } from '../../+item-page/item-page-routing-paths';
|
||||||
|
import {Bundle} from '../../core/shared/bundle.model';
|
||||||
|
import {Item} from '../../core/shared/item.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-edit-bitstream-page',
|
selector: 'ds-edit-bitstream-page',
|
||||||
@@ -299,12 +300,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
const bitstream$ = this.bitstreamRD$.pipe(
|
const bitstream$ = this.bitstreamRD$.pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
getRemoteDataPayload(),
|
getRemoteDataPayload()
|
||||||
switchMap((bitstream: Bitstream) => this.bitstreamService.findById(bitstream.id, followLink('format')).pipe(
|
|
||||||
getAllSucceededRemoteData(),
|
|
||||||
getRemoteDataPayload(),
|
|
||||||
filter((bs: Bitstream) => hasValue(bs)))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const allFormats$ = this.bitstreamFormatsRD$.pipe(
|
const allFormats$ = this.bitstreamFormatsRD$.pipe(
|
||||||
@@ -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
|
* When the item ID is present, navigate back to the item's edit bitstreams page,
|
||||||
* page the user came from
|
* otherwise retrieve the item ID based on the owning bundle's link
|
||||||
*/
|
*/
|
||||||
navigateToItemEditBitstreams() {
|
navigateToItemEditBitstreams() {
|
||||||
if (hasValue(this.itemId)) {
|
if (hasValue(this.itemId)) {
|
||||||
this.router.navigate([getItemEditRoute(this.itemId), 'bitstreams']);
|
this.router.navigate([getItemEditRoute(this.itemId), 'bitstreams']);
|
||||||
} else {
|
} 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']));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,8 @@ import { BITSTREAM } from './bitstream.resource-type';
|
|||||||
import { DSpaceObject } from './dspace-object.model';
|
import { DSpaceObject } from './dspace-object.model';
|
||||||
import { HALLink } from './hal-link.model';
|
import { HALLink } from './hal-link.model';
|
||||||
import { HALResource } from './hal-resource.model';
|
import { HALResource } from './hal-resource.model';
|
||||||
|
import {BUNDLE} from './bundle.resource-type';
|
||||||
|
import {Bundle} from './bundle.model';
|
||||||
|
|
||||||
@typedObject
|
@typedObject
|
||||||
@inheritSerialization(DSpaceObject)
|
@inheritSerialization(DSpaceObject)
|
||||||
@@ -57,4 +59,10 @@ export class Bitstream extends DSpaceObject implements HALResource {
|
|||||||
@link(BITSTREAM_FORMAT, false, 'format')
|
@link(BITSTREAM_FORMAT, false, 'format')
|
||||||
format?: Observable<RemoteData<BitstreamFormat>>;
|
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,6 +10,8 @@ import { RemoteData } from '../data/remote-data';
|
|||||||
import { PaginatedList } from '../data/paginated-list';
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
import { BITSTREAM } from './bitstream.resource-type';
|
import { BITSTREAM } from './bitstream.resource-type';
|
||||||
import { Bitstream } from './bitstream.model';
|
import { Bitstream } from './bitstream.model';
|
||||||
|
import {ITEM} from './item.resource-type';
|
||||||
|
import {Item} from './item.model';
|
||||||
|
|
||||||
@typedObject
|
@typedObject
|
||||||
@inheritSerialization(DSpaceObject)
|
@inheritSerialization(DSpaceObject)
|
||||||
@@ -24,6 +26,7 @@ export class Bundle extends DSpaceObject {
|
|||||||
self: HALLink;
|
self: HALLink;
|
||||||
primaryBitstream: HALLink;
|
primaryBitstream: HALLink;
|
||||||
bitstreams: HALLink;
|
bitstreams: HALLink;
|
||||||
|
item: HALLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,4 +42,11 @@ export class Bundle extends DSpaceObject {
|
|||||||
*/
|
*/
|
||||||
@link(BITSTREAM, true)
|
@link(BITSTREAM, true)
|
||||||
bitstreams?: Observable<RemoteData<PaginatedList<Bitstream>>>;
|
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>>;
|
||||||
}
|
}
|
||||||
|
@@ -33,9 +33,6 @@ export class SearchResultGridElementComponent<T extends SearchResult<K>, K exten
|
|||||||
protected bitstreamDataService: BitstreamDataService
|
protected bitstreamDataService: BitstreamDataService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
if (hasValue(this.object)) {
|
|
||||||
this.isCollapsed$ = this.isCollapsed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,6 +41,7 @@ export class SearchResultGridElementComponent<T extends SearchResult<K>, K exten
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (hasValue(this.object)) {
|
if (hasValue(this.object)) {
|
||||||
this.dso = this.object.indexableObject;
|
this.dso = this.object.indexableObject;
|
||||||
|
this.isCollapsed$ = this.isCollapsed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user