mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
switch to live rest-backend, still issue with bitstreams on item page
This commit is contained in:
@@ -2,10 +2,10 @@ module.exports = {
|
||||
// The REST API server settings.
|
||||
"rest": {
|
||||
"ssl": false,
|
||||
"address": "localhost",
|
||||
"port": 3000,
|
||||
"address": "dspace7.4science.it",
|
||||
"port": 80,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
"nameSpace": "/api"
|
||||
"nameSpace": "/dspace-spring-rest/api"
|
||||
},
|
||||
// Angular2 UI server settings.
|
||||
"ui": {
|
||||
|
@@ -45,6 +45,11 @@ export class RemoteDataBuildService {
|
||||
.map((entry: ResponseCacheEntry) => (<ErrorResponse> entry.response).errorMessage)
|
||||
.distinctUntilChanged();
|
||||
|
||||
const statusCode = responseCacheObs
|
||||
.filter((entry: ResponseCacheEntry) => hasValue(entry))
|
||||
.map((entry: ResponseCacheEntry) => entry.response.statusCode)
|
||||
.distinctUntilChanged();
|
||||
|
||||
const payload =
|
||||
Observable.race(
|
||||
this.objectCache.getBySelfLink<TNormalized>(href, normalizedType),
|
||||
@@ -70,6 +75,7 @@ export class RemoteDataBuildService {
|
||||
responsePending,
|
||||
isSuccessFul,
|
||||
errorMessage,
|
||||
statusCode,
|
||||
payload
|
||||
);
|
||||
}
|
||||
@@ -93,6 +99,11 @@ export class RemoteDataBuildService {
|
||||
.map((entry: ResponseCacheEntry) => (<ErrorResponse> entry.response).errorMessage)
|
||||
.distinctUntilChanged();
|
||||
|
||||
const statusCode = responseCacheObs
|
||||
.filter((entry: ResponseCacheEntry) => hasValue(entry))
|
||||
.map((entry: ResponseCacheEntry) => entry.response.statusCode)
|
||||
.distinctUntilChanged();
|
||||
|
||||
const payload = responseCacheObs
|
||||
.filter((entry: ResponseCacheEntry) => hasValue(entry) && entry.response.isSuccessful)
|
||||
.map((entry: ResponseCacheEntry) => (<SuccessResponse> entry.response).resourceUUIDs)
|
||||
@@ -112,6 +123,7 @@ export class RemoteDataBuildService {
|
||||
responsePending,
|
||||
isSuccessFul,
|
||||
errorMessage,
|
||||
statusCode,
|
||||
payload
|
||||
);
|
||||
}
|
||||
@@ -186,6 +198,18 @@ export class RemoteDataBuildService {
|
||||
.join(", ")
|
||||
);
|
||||
|
||||
const statusCode = Observable.combineLatest(
|
||||
...input.map(rd => rd.statusCode),
|
||||
).map((...statusCodes) => statusCodes
|
||||
.map((code, idx) => {
|
||||
if (hasValue(code)) {
|
||||
return `[${idx}]: ${code}`;
|
||||
}
|
||||
})
|
||||
.filter(c => hasValue(c))
|
||||
.join(", ")
|
||||
);
|
||||
|
||||
const payload = <Observable<T[]>> Observable.combineLatest(
|
||||
...input.map(rd => rd.payload)
|
||||
);
|
||||
@@ -199,6 +223,7 @@ export class RemoteDataBuildService {
|
||||
responsePending,
|
||||
isSuccessFul,
|
||||
errorMessage,
|
||||
statusCode,
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { inheritSerialization, autoserialize } from "cerialize";
|
||||
import { NormalizedDSpaceObject } from "./normalized-dspace-object.model";
|
||||
import { Bitstream } from "../../shared/bitstream.model";
|
||||
import { mapsTo } from "../builders/build-decorators";
|
||||
import { mapsTo, relationship } from "../builders/build-decorators";
|
||||
import { ResourceType } from "../../shared/resource-type";
|
||||
|
||||
@mapsTo(Bitstream)
|
||||
@inheritSerialization(NormalizedDSpaceObject)
|
||||
@@ -16,6 +17,7 @@ export class NormalizedBitstream extends NormalizedDSpaceObject {
|
||||
/**
|
||||
* The relative path to this Bitstream's file
|
||||
*/
|
||||
@autoserialize
|
||||
url: string;
|
||||
|
||||
/**
|
||||
@@ -27,23 +29,32 @@ export class NormalizedBitstream extends NormalizedDSpaceObject {
|
||||
/**
|
||||
* The format of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
format: string;
|
||||
|
||||
/**
|
||||
* The description of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* An array of Bundles that are direct parents of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Item)
|
||||
parents: Array<string>;
|
||||
|
||||
/**
|
||||
* The Bundle that owns this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Item)
|
||||
owner: string;
|
||||
|
||||
/**
|
||||
* The name of the Bundle this Bitstream is part of
|
||||
*/
|
||||
@autoserialize
|
||||
retrieve: string;
|
||||
bundleName: string;
|
||||
}
|
||||
|
@@ -20,13 +20,17 @@ export class NormalizedCollection extends NormalizedDSpaceObject {
|
||||
logo: string;
|
||||
|
||||
/**
|
||||
* An array of Collections that are direct parents of this Collection
|
||||
* An array of Communities that are direct parents of this Collection
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Community)
|
||||
parents: Array<string>;
|
||||
|
||||
/**
|
||||
* The Collection that owns this Collection
|
||||
* The Community that owns this Collection
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Community)
|
||||
owner: string;
|
||||
|
||||
@autoserialize
|
||||
|
@@ -22,11 +22,15 @@ export class NormalizedCommunity extends NormalizedDSpaceObject {
|
||||
/**
|
||||
* An array of Communities that are direct parents of this Community
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Community)
|
||||
parents: Array<string>;
|
||||
|
||||
/**
|
||||
* The Community that owns this Community
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Community)
|
||||
owner: string;
|
||||
|
||||
@autoserialize
|
||||
|
@@ -13,8 +13,11 @@ export abstract class NormalizedDSpaceObject implements CacheableObject {
|
||||
|
||||
/**
|
||||
* The human-readable identifier of this DSpaceObject
|
||||
*
|
||||
* Currently mapped to uuid but left in to leave room
|
||||
* for a shorter, more user friendly type of id
|
||||
*/
|
||||
@autoserialize
|
||||
@autoserializeAs(String, 'uuid')
|
||||
id: string;
|
||||
|
||||
/**
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { inheritSerialization, autoserialize } from "cerialize";
|
||||
import { inheritSerialization, autoserialize, autoserializeAs } from "cerialize";
|
||||
import { NormalizedDSpaceObject } from "./normalized-dspace-object.model";
|
||||
import { Item } from "../../shared/item.model";
|
||||
import { mapsTo, relationship } from "../builders/build-decorators";
|
||||
@@ -17,16 +17,25 @@ export class NormalizedItem extends NormalizedDSpaceObject {
|
||||
/**
|
||||
* The Date of the last modification of this Item
|
||||
*/
|
||||
@autoserialize
|
||||
lastModified: Date;
|
||||
|
||||
/**
|
||||
* A boolean representing if this Item is currently archived or not
|
||||
*/
|
||||
@autoserializeAs(Boolean, 'inArchive')
|
||||
isArchived: boolean;
|
||||
|
||||
/**
|
||||
* A boolean representing if this Item is currently discoverable or not
|
||||
*/
|
||||
@autoserializeAs(Boolean, 'discoverable')
|
||||
isDiscoverable: boolean;
|
||||
|
||||
/**
|
||||
* A boolean representing if this Item is currently withdrawn or not
|
||||
*/
|
||||
@autoserializeAs(Boolean, 'withdrawn')
|
||||
isWithdrawn: boolean;
|
||||
|
||||
/**
|
||||
@@ -39,9 +48,11 @@ export class NormalizedItem extends NormalizedDSpaceObject {
|
||||
/**
|
||||
* The Collection that owns this Item
|
||||
*/
|
||||
@autoserializeAs(String, 'owningCollection')
|
||||
@relationship(ResourceType.Collection)
|
||||
owner: string;
|
||||
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Bundle)
|
||||
bundles: Array<string>;
|
||||
@relationship(ResourceType.Bitstream)
|
||||
bitstreams: Array<string>;
|
||||
}
|
||||
|
17
src/app/core/cache/response-cache.models.ts
vendored
17
src/app/core/cache/response-cache.models.ts
vendored
@@ -1,18 +1,25 @@
|
||||
import { RequestError } from "../data/request.models";
|
||||
export class Response {
|
||||
constructor(public isSuccessful: boolean) {}
|
||||
constructor(
|
||||
public isSuccessful: boolean,
|
||||
public statusCode: string
|
||||
) {}
|
||||
}
|
||||
|
||||
export class SuccessResponse extends Response {
|
||||
constructor(public resourceUUIDs: Array<String>) {
|
||||
super(true);
|
||||
constructor(
|
||||
public resourceUUIDs: Array<String>,
|
||||
public statusCode: string
|
||||
) {
|
||||
super(true, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorResponse extends Response {
|
||||
errorMessage: string;
|
||||
|
||||
constructor(error: Error) {
|
||||
super(false);
|
||||
constructor(error: RequestError) {
|
||||
super(false, error.statusText);
|
||||
console.error(error);
|
||||
this.errorMessage = error.message;
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ import { RemoteDataBuildService } from "../cache/builders/remote-data-build.serv
|
||||
|
||||
@Injectable()
|
||||
export class CollectionDataService extends DataService<NormalizedCollection, Collection> {
|
||||
protected endpoint = '/collections';
|
||||
protected endpoint = '/core/collections';
|
||||
|
||||
constructor(
|
||||
protected objectCache: ObjectCacheService,
|
||||
|
@@ -11,7 +11,7 @@ import { RemoteDataBuildService } from "../cache/builders/remote-data-build.serv
|
||||
|
||||
@Injectable()
|
||||
export class CommunityDataService extends DataService<NormalizedCommunity, Community> {
|
||||
protected endpoint = '/communities';
|
||||
protected endpoint = '/core/communities';
|
||||
|
||||
constructor(
|
||||
protected objectCache: ObjectCacheService,
|
||||
|
@@ -11,7 +11,7 @@ import { RemoteDataBuildService } from "../cache/builders/remote-data-build.serv
|
||||
|
||||
@Injectable()
|
||||
export class ItemDataService extends DataService<NormalizedItem, Item> {
|
||||
protected endpoint = '/items';
|
||||
protected endpoint = '/core/items';
|
||||
|
||||
constructor(
|
||||
protected objectCache: ObjectCacheService,
|
||||
|
@@ -17,6 +17,7 @@ export class RemoteData<T> {
|
||||
private responsePending: Observable<boolean>,
|
||||
private isSuccessFul: Observable<boolean>,
|
||||
public errorMessage: Observable<string>,
|
||||
public statusCode: Observable<string>,
|
||||
public payload: Observable<T>
|
||||
) {
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Injectable, Inject } from "@angular/core";
|
||||
import { Actions, Effect } from "@ngrx/effects";
|
||||
import { Store } from "@ngrx/store";
|
||||
import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service";
|
||||
import { ObjectCacheService } from "../cache/object-cache.service";
|
||||
import { DSpaceRESTV2Response } from "../dspace-rest-v2/dspace-rest-v2-response.model";
|
||||
@@ -10,7 +9,7 @@ import { Observable } from "rxjs";
|
||||
import { Response, SuccessResponse, ErrorResponse } from "../cache/response-cache.models";
|
||||
import { hasNoValue, hasValue, isEmpty, isNotEmpty } from "../../shared/empty.util";
|
||||
import { GlobalConfig, GLOBAL_CONFIG } from "../../../config";
|
||||
import { RequestState, RequestEntry } from "./request.reducer";
|
||||
import { RequestEntry } from "./request.reducer";
|
||||
import {
|
||||
RequestActionTypes, RequestExecuteAction,
|
||||
RequestCompleteAction
|
||||
@@ -19,11 +18,16 @@ import { ResponseCacheService } from "../cache/response-cache.service";
|
||||
import { RequestService } from "./request.service";
|
||||
import { NormalizedObjectFactory } from "../cache/models/normalized-object-factory";
|
||||
import { ResourceType } from "../shared/resource-type";
|
||||
import { RequestError } from "./request.models";
|
||||
|
||||
function isObjectLevel(halObj: any) {
|
||||
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
|
||||
}
|
||||
|
||||
function isPaginatedResponse(halObj: any) {
|
||||
return isNotEmpty(halObj.page) && hasValue(halObj._embedded);
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class RequestEffects {
|
||||
|
||||
@@ -33,8 +37,7 @@ export class RequestEffects {
|
||||
private restApi: DSpaceRESTv2Service,
|
||||
private objectCache: ObjectCacheService,
|
||||
private responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
private store: Store<RequestState>
|
||||
protected requestService: RequestService
|
||||
) { }
|
||||
|
||||
@Effect() execute = this.actions$
|
||||
@@ -45,27 +48,31 @@ export class RequestEffects {
|
||||
})
|
||||
.flatMap((entry: RequestEntry) => {
|
||||
return this.restApi.get(entry.request.href)
|
||||
.map((data: DSpaceRESTV2Response) => this.processEmbedded(data._embedded))
|
||||
.map((ids: Array<string>) => new SuccessResponse(ids))
|
||||
.map((data: DSpaceRESTV2Response) => new SuccessResponse(this.process(data.payload), data.statusCode))
|
||||
.do((response: Response) => this.responseCache.add(entry.request.href, response, this.EnvConfig.cache.msToLive))
|
||||
.map((response: Response) => new RequestCompleteAction(entry.request.href))
|
||||
.catch((error: Error) => Observable.of(new ErrorResponse(error))
|
||||
.catch((error: RequestError) => Observable.of(new ErrorResponse(error))
|
||||
.do((response: Response) => this.responseCache.add(entry.request.href, response, this.EnvConfig.cache.msToLive))
|
||||
.map((response: Response) => new RequestCompleteAction(entry.request.href)));
|
||||
});
|
||||
|
||||
protected processEmbedded(_embedded: any): Array<string> {
|
||||
protected process(data: any): Array<string> {
|
||||
|
||||
if (isNotEmpty(_embedded)) {
|
||||
if (isObjectLevel(_embedded)) {
|
||||
return this.deserializeAndCache(_embedded);
|
||||
if (isNotEmpty(data)) {
|
||||
if (isPaginatedResponse(data)) {
|
||||
//TODO parse page object
|
||||
return this.process(data._embedded);
|
||||
}
|
||||
else if (isObjectLevel(data)) {
|
||||
return this.deserializeAndCache(data);
|
||||
}
|
||||
else {
|
||||
let uuids = [];
|
||||
Object.keys(_embedded)
|
||||
.filter(property => _embedded.hasOwnProperty(property))
|
||||
Object.keys(data)
|
||||
.filter(property => data.hasOwnProperty(property))
|
||||
.filter(property => hasValue(data[property]))
|
||||
.forEach(property => {
|
||||
uuids = [...uuids, ...this.deserializeAndCache(_embedded[property])];
|
||||
uuids = [...uuids, ...this.deserializeAndCache(data[property])];
|
||||
});
|
||||
return uuids;
|
||||
}
|
||||
@@ -96,7 +103,7 @@ export class RequestEffects {
|
||||
if (isArray) {
|
||||
obj.forEach(o => {
|
||||
if (isNotEmpty(o._embedded)) {
|
||||
this.processEmbedded(o._embedded);
|
||||
this.process(o._embedded);
|
||||
}
|
||||
});
|
||||
const normalizedObjArr = serializer.deserializeArray(obj);
|
||||
@@ -105,7 +112,7 @@ export class RequestEffects {
|
||||
}
|
||||
else {
|
||||
if (isNotEmpty(obj._embedded)) {
|
||||
this.processEmbedded(obj._embedded);
|
||||
this.process(obj._embedded);
|
||||
}
|
||||
const normalizedObj = serializer.deserialize(obj);
|
||||
this.addToObjectCache(normalizedObj);
|
||||
|
@@ -27,3 +27,7 @@ export class FindAllRequest<T> extends Request<T> {
|
||||
super(href);
|
||||
}
|
||||
}
|
||||
|
||||
export class RequestError extends Error {
|
||||
statusText: string;
|
||||
}
|
||||
|
@@ -1,4 +1,7 @@
|
||||
export interface DSpaceRESTV2Response {
|
||||
payload: {
|
||||
_embedded?: any;
|
||||
_links?: any;
|
||||
},
|
||||
statusCode: string
|
||||
}
|
||||
|
@@ -26,10 +26,8 @@ export class DSpaceRESTv2Serializer<T> implements Serializer<T> {
|
||||
* @param model The model to serialize
|
||||
* @returns An object to send to the backend
|
||||
*/
|
||||
serialize(model: T): DSpaceRESTV2Response {
|
||||
return {
|
||||
"_embedded": Serialize(model, this.modelType)
|
||||
};
|
||||
serialize(model: T): any {
|
||||
return Serialize(model, this.modelType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,10 +36,8 @@ export class DSpaceRESTv2Serializer<T> implements Serializer<T> {
|
||||
* @param models The array of models to serialize
|
||||
* @returns An object to send to the backend
|
||||
*/
|
||||
serializeArray(models: Array<T>): DSpaceRESTV2Response {
|
||||
return {
|
||||
"_embedded": Serialize(models, this.modelType)
|
||||
};
|
||||
serializeArray(models: Array<T>): any {
|
||||
return Serialize(models, this.modelType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -4,6 +4,7 @@ import { Observable } from 'rxjs/Observable';
|
||||
import { RESTURLCombiner } from "../url-combiner/rest-url-combiner";
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
import { DSpaceRESTV2Response } from "./dspace-rest-v2-response.model";
|
||||
|
||||
/**
|
||||
* Service to access DSpace's REST API
|
||||
@@ -24,9 +25,9 @@ export class DSpaceRESTv2Service {
|
||||
* @return {Observable<string>}
|
||||
* An Observablse<string> containing the response from the server
|
||||
*/
|
||||
get(relativeURL: string, options?: RequestOptionsArgs): Observable<string> {
|
||||
get(relativeURL: string, options?: RequestOptionsArgs): Observable<DSpaceRESTV2Response> {
|
||||
return this.http.get(new RESTURLCombiner(this.EnvConfig, relativeURL).toString(), options)
|
||||
.map(res => res.json())
|
||||
.map(res => ({ payload: res.json(), statusCode: res.statusText }))
|
||||
.catch(err => {
|
||||
console.log('Error: ', err);
|
||||
return Observable.throw(err);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { DSpaceObject } from "./dspace-object.model";
|
||||
import { Bundle } from "./bundle.model";
|
||||
import { RemoteData } from "../data/remote-data";
|
||||
import { Item } from "./item.model";
|
||||
|
||||
export class Bitstream extends DSpaceObject {
|
||||
|
||||
@@ -25,14 +25,19 @@ export class Bitstream extends DSpaceObject {
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* An array of Bundles that are direct parents of this Bitstream
|
||||
* The name of the Bundle this Bitstream is part of
|
||||
*/
|
||||
parents: RemoteData<Bundle[]>;
|
||||
bundleName: string;
|
||||
|
||||
/**
|
||||
* An array of Items that are direct parents of this Bitstream
|
||||
*/
|
||||
parents: RemoteData<Item[]>;
|
||||
|
||||
/**
|
||||
* The Bundle that owns this Bitstream
|
||||
*/
|
||||
owner: Bundle;
|
||||
owner: RemoteData<Item>;
|
||||
|
||||
/**
|
||||
* The Bundle that owns this Bitstream
|
||||
|
@@ -17,7 +17,7 @@ export class Bundle extends DSpaceObject {
|
||||
/**
|
||||
* The Item that owns this Bundle
|
||||
*/
|
||||
owner: Item;
|
||||
owner: RemoteData<Item>;
|
||||
|
||||
bitstreams: RemoteData<Bitstream[]>
|
||||
|
||||
|
@@ -63,7 +63,7 @@ export class Collection extends DSpaceObject {
|
||||
/**
|
||||
* The Collection that owns this Collection
|
||||
*/
|
||||
owner: Collection;
|
||||
owner: RemoteData<Collection>;
|
||||
|
||||
items: RemoteData<Item[]>;
|
||||
|
||||
|
@@ -55,7 +55,7 @@ export class Community extends DSpaceObject {
|
||||
/**
|
||||
* The Community that owns this Community
|
||||
*/
|
||||
owner: Community;
|
||||
owner: RemoteData<Community>;
|
||||
|
||||
collections: RemoteData<Collection[]>;
|
||||
|
||||
|
@@ -44,7 +44,7 @@ export abstract class DSpaceObject implements CacheableObject {
|
||||
/**
|
||||
* The DSpaceObject that owns this DSpaceObject
|
||||
*/
|
||||
owner: DSpaceObject;
|
||||
owner: RemoteData<DSpaceObject>;
|
||||
|
||||
/**
|
||||
* Find a metadata field by key and language
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import { DSpaceObject } from "./dspace-object.model";
|
||||
import { Collection } from "./collection.model";
|
||||
import { RemoteData } from "../data/remote-data";
|
||||
import { Bundle } from "./bundle.model";
|
||||
import { Bitstream } from "./bitstream.model";
|
||||
import { Observable } from "rxjs";
|
||||
import { hasValue } from "../../shared/empty.util";
|
||||
import { isNotEmpty } from "../../shared/empty.util";
|
||||
|
||||
export class Item extends DSpaceObject {
|
||||
|
||||
@@ -23,6 +22,11 @@ export class Item extends DSpaceObject {
|
||||
*/
|
||||
isArchived: boolean;
|
||||
|
||||
/**
|
||||
* A boolean representing if this Item is currently discoverable or not
|
||||
*/
|
||||
isDiscoverable: boolean;
|
||||
|
||||
/**
|
||||
* A boolean representing if this Item is currently withdrawn or not
|
||||
*/
|
||||
@@ -36,9 +40,9 @@ export class Item extends DSpaceObject {
|
||||
/**
|
||||
* The Collection that owns this Item
|
||||
*/
|
||||
owner: Collection;
|
||||
owner: RemoteData<Collection>;
|
||||
|
||||
bundles: RemoteData<Bundle[]>;
|
||||
bitstreams: RemoteData<Bitstream[]>;
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,11 +50,12 @@ export class Item extends DSpaceObject {
|
||||
* @returns {Observable<Bitstream>} the primaryBitstream of the "THUMBNAIL" bundle
|
||||
*/
|
||||
getThumbnail(): Observable<Bitstream> {
|
||||
const bundle: Observable<Bundle> = this.getBundle("THUMBNAIL");
|
||||
return bundle
|
||||
.filter(bundle => hasValue(bundle))
|
||||
.flatMap(bundle => bundle.primaryBitstream.payload)
|
||||
.startWith(undefined);
|
||||
//TODO currently this just picks the first thumbnail
|
||||
//should be adjusted when we have a way to determine
|
||||
//the primary thumbnail from rest
|
||||
return this.getBitstreamsByBundleName("THUMBNAIL")
|
||||
.filter(thumbnails => isNotEmpty(thumbnails))
|
||||
.map(thumbnails => thumbnails[0])
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,45 +63,31 @@ export class Item extends DSpaceObject {
|
||||
* @returns {Observable<Bitstream>} the primaryBitstream of the "THUMBNAIL" bundle
|
||||
*/
|
||||
getThumbnailForOriginal(original: Bitstream): Observable<Bitstream> {
|
||||
const bundle: Observable<Bundle> = this.getBundle("THUMBNAIL");
|
||||
return bundle
|
||||
.filter(bundle => hasValue(bundle))
|
||||
.flatMap(bundle => bundle
|
||||
.bitstreams.payload.map(files => files
|
||||
return this.getBitstreamsByBundleName("THUMBNAIL").map(files => files
|
||||
.find(thumbnail => thumbnail
|
||||
.name.startsWith(original.name)
|
||||
)
|
||||
)
|
||||
)
|
||||
.startWith(undefined);;
|
||||
).startWith(undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all files that should be displayed on the item page of this item
|
||||
* @returns {Observable<Array<Observable<Bitstream>>>} an array of all Bitstreams in the "ORIGINAL" bundle
|
||||
*/
|
||||
getFiles(name: String = "ORIGINAL"): Observable<Bitstream[]> {
|
||||
const bundle: Observable <Bundle> = this.getBundle(name);
|
||||
return bundle
|
||||
.filter(bundle => hasValue(bundle))
|
||||
.flatMap(bundle => bundle.bitstreams.payload)
|
||||
.startWith([]);
|
||||
getFiles(): Observable<Bitstream[]> {
|
||||
return this.getBitstreamsByBundleName("ORIGINAL");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the bundle of this item by its name
|
||||
* @param name The name of the Bundle that should be returned
|
||||
* @returns {Observable<Bundle>} the Bundle that belongs to this item with the given name
|
||||
* Retrieves bitstreams by bundle name
|
||||
* @param bundleName The name of the Bundle that should be returned
|
||||
* @returns {Observable<Bitstream[]>} the bitstreams with the given bundleName
|
||||
*/
|
||||
getBundle(name: String): Observable<Bundle> {
|
||||
return this.bundles.payload
|
||||
.filter(bundles => hasValue(bundles))
|
||||
.map(bundles => {
|
||||
return bundles.find((bundle: Bundle) => {
|
||||
return bundle.name === name
|
||||
});
|
||||
})
|
||||
.startWith(undefined);
|
||||
getBitstreamsByBundleName(bundleName: string): Observable<Bitstream[]> {
|
||||
return this.bitstreams.payload.startWith([])
|
||||
.map(bitstreams => bitstreams
|
||||
.filter(bitstream => bitstream.bundleName === bundleName)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Collection } from "../../../core/shared/collection.model";
|
||||
import { Observable } from "rxjs";
|
||||
import { Item } from "../../../core/shared/item.model";
|
||||
import { RemoteDataBuildService } from "../../../core/cache/builders/remote-data-build.service";
|
||||
|
||||
/**
|
||||
* This component renders the parent collections section of the item
|
||||
@@ -22,7 +23,9 @@ export class CollectionsComponent implements OnInit {
|
||||
|
||||
collections: Observable<Collection[]>;
|
||||
|
||||
constructor() {
|
||||
constructor(
|
||||
private rdbs: RemoteDataBuildService
|
||||
) {
|
||||
this.universalInit();
|
||||
|
||||
}
|
||||
@@ -31,7 +34,11 @@ export class CollectionsComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.collections = this.item.parents.payload;
|
||||
// this.collections = this.item.parents.payload;
|
||||
//TODO this should use parents, but the collections
|
||||
// for an Item aren't returned by the REST API yet,
|
||||
// only the owning collection
|
||||
this.collections = this.rdbs.aggregate([this.item.owner]).payload
|
||||
}
|
||||
|
||||
|
||||
|
@@ -35,8 +35,8 @@ export class FullFileSectionComponent extends FileSectionComponent implements On
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
const originals = this.item.getFiles("ORIGINAL");
|
||||
const licenses = this.item.getFiles("LICENSE");
|
||||
const originals = this.item.getFiles();
|
||||
const licenses = this.item.getBitstreamsByBundleName("LICENSE");
|
||||
this.files = Observable.combineLatest(originals, licenses, (originals, licenses) => [...originals, ...licenses]);
|
||||
this.files.subscribe(
|
||||
files =>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<ds-metadata-field-wrapper [label]="label | translate">
|
||||
<div class="file-section">
|
||||
<a *ngFor="let file of (files | async); let last=last;" [href]="file?.retrieve">
|
||||
<a *ngFor="let file of (files | async); let last=last;" [href]="file?.url">
|
||||
<span>{{file?.name}}</span>
|
||||
<span>({{(file?.size) | dsFileSize }})</span>
|
||||
<span *ngIf="!last" innerHTML="{{separator}}"></span>
|
||||
|
Reference in New Issue
Block a user