mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
intermediate commit
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<div *ngIf="subCollectionsRD?.hasSucceeded" @fadeIn>
|
<div *ngIf="subCollectionsRD?.hasSucceeded" @fadeIn>
|
||||||
<h2>{{'community.sub-collection-list.head' | translate}}</h2>
|
<h2>{{'community.sub-collection-list.head' | translate}}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let collection of subCollectionsRD?.payload">
|
<li *ngFor="let collection of subCollectionsRD?.payload.page">
|
||||||
<p>
|
<p>
|
||||||
<span class="lead"><a [routerLink]="['/collections', collection.id]">{{collection.name}}</a></span><br>
|
<span class="lead"><a [routerLink]="['/collections', collection.id]">{{collection.name}}</a></span><br>
|
||||||
<span class="text-muted">{{collection.shortDescription}}</span>
|
<span class="text-muted">{{collection.shortDescription}}</span>
|
||||||
|
@@ -6,6 +6,7 @@ import { Collection } from '../../core/shared/collection.model';
|
|||||||
import { Community } from '../../core/shared/community.model';
|
import { Community } from '../../core/shared/community.model';
|
||||||
|
|
||||||
import { fadeIn } from '../../shared/animations/fade';
|
import { fadeIn } from '../../shared/animations/fade';
|
||||||
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-community-page-sub-collection-list',
|
selector: 'ds-community-page-sub-collection-list',
|
||||||
@@ -15,7 +16,7 @@ import { fadeIn } from '../../shared/animations/fade';
|
|||||||
})
|
})
|
||||||
export class CommunityPageSubCollectionListComponent implements OnInit {
|
export class CommunityPageSubCollectionListComponent implements OnInit {
|
||||||
@Input() community: Community;
|
@Input() community: Community;
|
||||||
subCollectionsRDObs: Observable<RemoteData<Collection[]>>;
|
subCollectionsRDObs: Observable<RemoteData<PaginatedList<Collection>>>;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.subCollectionsRDObs = this.community.collections;
|
this.subCollectionsRDObs = this.community.collections;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<ds-metadata-field-wrapper [label]="label | translate">
|
<ds-metadata-field-wrapper *ngIf="hasSucceeded() | async" [label]="label | translate">
|
||||||
<div class="collections">
|
<div class="collections">
|
||||||
<a *ngFor="let collection of (collections | async); let last=last;" [routerLink]="['/collections', collection.id]">
|
<a *ngFor="let collection of (collections | async); let last=last;" [routerLink]="['/collections', collection.id]">
|
||||||
<span>{{collection?.name}}</span><span *ngIf="!last" [innerHTML]="separator"></span>
|
<span>{{collection?.name}}</span><span *ngIf="!last" [innerHTML]="separator"></span>
|
||||||
|
@@ -38,4 +38,8 @@ export class CollectionsComponent implements OnInit {
|
|||||||
this.collections = this.item.owner.map((rd: RemoteData<Collection>) => [rd.payload]);
|
this.collections = this.item.owner.map((rd: RemoteData<Collection>) => [rd.payload]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasSucceeded() {
|
||||||
|
this.item.owner.map((rd: RemoteData<Collection>) => rd.hasSucceeded)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -85,6 +85,7 @@ export class RemoteDataBuildService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toRemoteDataObservable<T>(requestEntryObs: Observable<RequestEntry>, responseCacheObs: Observable<ResponseCacheEntry>, payloadObs: Observable<T>) {
|
toRemoteDataObservable<T>(requestEntryObs: Observable<RequestEntry>, responseCacheObs: Observable<ResponseCacheEntry>, payloadObs: Observable<T>) {
|
||||||
|
|
||||||
return Observable.combineLatest(requestEntryObs, responseCacheObs.startWith(undefined), payloadObs,
|
return Observable.combineLatest(requestEntryObs, responseCacheObs.startWith(undefined), payloadObs,
|
||||||
(reqEntry: RequestEntry, resEntry: ResponseCacheEntry, payload: T) => {
|
(reqEntry: RequestEntry, resEntry: ResponseCacheEntry, payload: T) => {
|
||||||
const requestPending = hasValue(reqEntry.requestPending) ? reqEntry.requestPending : true;
|
const requestPending = hasValue(reqEntry.requestPending) ? reqEntry.requestPending : true;
|
||||||
@@ -98,7 +99,6 @@ export class RemoteDataBuildService {
|
|||||||
error = new RemoteDataError(resEntry.response.statusCode, errorMessage);
|
error = new RemoteDataError(resEntry.response.statusCode, errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RemoteData(
|
return new RemoteData(
|
||||||
requestPending,
|
requestPending,
|
||||||
responsePending,
|
responsePending,
|
||||||
@@ -109,7 +109,7 @@ export class RemoteDataBuildService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
buildList<TNormalized extends NormalizedObject, TDomain>(hrefObs: string | Observable<string>): Observable<RemoteData<TDomain[] | PaginatedList<TDomain>>> {
|
buildList<TNormalized extends NormalizedObject, TDomain>(hrefObs: string | Observable<string>): Observable<RemoteData<PaginatedList<TDomain>>> {
|
||||||
if (typeof hrefObs === 'string') {
|
if (typeof hrefObs === 'string') {
|
||||||
hrefObs = Observable.of(hrefObs);
|
hrefObs = Observable.of(hrefObs);
|
||||||
}
|
}
|
||||||
@@ -147,11 +147,7 @@ export class RemoteDataBuildService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const payloadObs = Observable.combineLatest(tDomainListObs, pageInfoObs, (tDomainList, pageInfo) => {
|
const payloadObs = Observable.combineLatest(tDomainListObs, pageInfoObs, (tDomainList, pageInfo) => {
|
||||||
if (hasValue(pageInfo)) {
|
return new PaginatedList(pageInfo, tDomainList);
|
||||||
return new PaginatedList(pageInfo, tDomainList);
|
|
||||||
} else {
|
|
||||||
return tDomainList;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.toRemoteDataObservable(requestEntryObs, responseCacheObs, payloadObs);
|
return this.toRemoteDataObservable(requestEntryObs, responseCacheObs, payloadObs);
|
||||||
|
46
src/app/core/cache/models/normalized-bitstream-format.model.ts
vendored
Normal file
46
src/app/core/cache/models/normalized-bitstream-format.model.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||||
|
|
||||||
|
import { mapsTo } from '../builders/build-decorators';
|
||||||
|
import { BitstreamFormat } from '../../shared/bitstream-format.model';
|
||||||
|
import { NormalizedObject } from './normalized-object.model';
|
||||||
|
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||||
|
|
||||||
|
// While BitstreamFormats don't have a UUID, but need to be cachable: use this serializer. Remove it when the REST API returns them with UUID
|
||||||
|
const BitstreamFormatUUIDSerializer = {
|
||||||
|
Serialize(json: any): any {
|
||||||
|
// No need to serialize again, de ID is already serialized by the id field itself
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
Deserialize(json: any): any {
|
||||||
|
return 'bitstream-format-' + json.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@mapsTo(BitstreamFormat)
|
||||||
|
@inheritSerialization(NormalizedObject)
|
||||||
|
export class NormalizedBitstreamFormat extends NormalizedObject {
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
shortDescription: string;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
mimetype: string;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
supportLevel: number;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
internal: boolean;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
extensions: string;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@autoserializeAs(BitstreamFormatUUIDSerializer)
|
||||||
|
uuid: string;
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
import { autoserialize, inheritSerialization, autoserializeAs } from 'cerialize';
|
import { autoserialize, inheritSerialization } from 'cerialize';
|
||||||
|
|
||||||
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||||
import { Collection } from '../../shared/collection.model';
|
import { Collection } from '../../shared/collection.model';
|
||||||
|
@@ -49,6 +49,7 @@ export class NormalizedItem extends NormalizedDSpaceObject {
|
|||||||
/**
|
/**
|
||||||
* The Collection that owns this Item
|
* The Collection that owns this Item
|
||||||
*/
|
*/
|
||||||
|
@autoserialize
|
||||||
@relationship(ResourceType.Collection, false)
|
@relationship(ResourceType.Collection, false)
|
||||||
owningCollection: string;
|
owningCollection: string;
|
||||||
|
|
||||||
|
@@ -6,6 +6,8 @@ import { GenericConstructor } from '../../shared/generic-constructor';
|
|||||||
import { NormalizedCommunity } from './normalized-community.model';
|
import { NormalizedCommunity } from './normalized-community.model';
|
||||||
import { ResourceType } from '../../shared/resource-type';
|
import { ResourceType } from '../../shared/resource-type';
|
||||||
import { NormalizedObject } from './normalized-object.model';
|
import { NormalizedObject } from './normalized-object.model';
|
||||||
|
import { NormalizedBitstreamFormat } from './normalized-bitstream-format.model';
|
||||||
|
import { NormalizedResourcePolicy } from './normalized-resource-policy.model';
|
||||||
|
|
||||||
export class NormalizedObjectFactory {
|
export class NormalizedObjectFactory {
|
||||||
public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject> {
|
public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject> {
|
||||||
@@ -25,6 +27,12 @@ export class NormalizedObjectFactory {
|
|||||||
case ResourceType.Community: {
|
case ResourceType.Community: {
|
||||||
return NormalizedCommunity
|
return NormalizedCommunity
|
||||||
}
|
}
|
||||||
|
case ResourceType.BitstreamFormat: {
|
||||||
|
return NormalizedBitstreamFormat
|
||||||
|
}
|
||||||
|
case ResourceType.ResourcePolicy: {
|
||||||
|
return NormalizedResourcePolicy
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
34
src/app/core/cache/models/normalized-resource-policy.model.ts
vendored
Normal file
34
src/app/core/cache/models/normalized-resource-policy.model.ts
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||||
|
|
||||||
|
import { mapsTo } from '../builders/build-decorators';
|
||||||
|
import { BitstreamFormat } from '../../shared/bitstream-format.model';
|
||||||
|
import { NormalizedObject } from './normalized-object.model';
|
||||||
|
import { ResourcePolicy } from '../../shared/resource-policy.model';
|
||||||
|
|
||||||
|
// While ResourcePolicyUUIDSerializer don't have a UUID, but need to be cachable: use this serializer. Remove it when the REST API returns them with UUID
|
||||||
|
const ResourcePolicyUUIDSerializer = {
|
||||||
|
Serialize(json: any): any {
|
||||||
|
// No need to serialize again, de ID is already serialized by the id field itself
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
Deserialize(json: any): any {
|
||||||
|
return 'resource-policy-' + json.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@mapsTo(ResourcePolicy)
|
||||||
|
@inheritSerialization(NormalizedObject)
|
||||||
|
export class NormalizedResourcePolicy extends NormalizedObject {
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@autoserializeAs(String, 'groupUUID')
|
||||||
|
group: string;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@autoserializeAs(ResourcePolicyUUIDSerializer)
|
||||||
|
uuid: string;
|
||||||
|
}
|
@@ -4,8 +4,9 @@ import { CacheableObject } from '../cache/object-cache.reducer';
|
|||||||
import { PageInfo } from '../shared/page-info.model';
|
import { PageInfo } from '../shared/page-info.model';
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
|
||||||
import { GenericConstructor } from '../shared/generic-constructor';
|
import { GenericConstructor } from '../shared/generic-constructor';
|
||||||
|
import { PaginatedList } from './paginated-list';
|
||||||
|
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||||
|
|
||||||
function isObjectLevel(halObj: any) {
|
function isObjectLevel(halObj: any) {
|
||||||
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
|
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
|
||||||
@@ -17,96 +18,93 @@ function isPaginatedResponse(halObj: any) {
|
|||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
|
|
||||||
class ProcessRequestDTO<ObjectDomain> {
|
|
||||||
[key: string]: ObjectDomain[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class BaseResponseParsingService {
|
export abstract class BaseResponseParsingService {
|
||||||
protected abstract EnvConfig: GlobalConfig;
|
protected abstract EnvConfig: GlobalConfig;
|
||||||
protected abstract objectCache: ObjectCacheService;
|
protected abstract objectCache: ObjectCacheService;
|
||||||
protected abstract objectFactory: any;
|
protected abstract objectFactory: any;
|
||||||
protected abstract toCache: boolean;
|
protected abstract toCache: boolean;
|
||||||
|
|
||||||
protected process<ObjectDomain,ObjectType>(data: any, requestHref: string): ProcessRequestDTO<ObjectDomain> {
|
protected process<ObjectDomain, ObjectType>(data: any, requestHref: string): any {
|
||||||
|
|
||||||
if (isNotEmpty(data)) {
|
if (isNotEmpty(data)) {
|
||||||
if (isPaginatedResponse(data)) {
|
if (hasNoValue(data) || (typeof data !== 'object')) {
|
||||||
return this.process(data._embedded, requestHref);
|
return data;
|
||||||
|
} else if (isPaginatedResponse(data)) {
|
||||||
|
return this.processPaginatedList(data, requestHref);
|
||||||
|
} else if (Array.isArray(data)) {
|
||||||
|
return this.processArray(data, requestHref);
|
||||||
} else if (isObjectLevel(data)) {
|
} else if (isObjectLevel(data)) {
|
||||||
return { topLevel: this.deserializeAndCache(data, requestHref) };
|
const object = this.deserialize(data, requestHref);
|
||||||
} else {
|
this.cache(object, requestHref);
|
||||||
const result = new ProcessRequestDTO<ObjectDomain>();
|
if (isNotEmpty(data._embedded)) {
|
||||||
if (Array.isArray(data)) {
|
const list = {};
|
||||||
result.topLevel = [];
|
Object
|
||||||
data.forEach((datum) => {
|
.keys(data._embedded)
|
||||||
if (isPaginatedResponse(datum)) {
|
.filter((property) => data._embedded.hasOwnProperty(property))
|
||||||
const obj = this.process(datum, requestHref);
|
|
||||||
result.topLevel = [...result.topLevel, ...this.flattenSingleKeyObject(obj)];
|
|
||||||
} else {
|
|
||||||
result.topLevel = [...result.topLevel, ...this.deserializeAndCache<ObjectDomain,ObjectType>(datum, requestHref)];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Object.keys(data)
|
|
||||||
.filter((property) => data.hasOwnProperty(property))
|
|
||||||
.filter((property) => hasValue(data[property]))
|
|
||||||
.forEach((property) => {
|
.forEach((property) => {
|
||||||
if (isPaginatedResponse(data[property])) {
|
console.log(data._embedded[property]);
|
||||||
const obj = this.process(data[property], requestHref);
|
const parsedObj = this.process<ObjectDomain, ObjectType>(data._embedded[property], requestHref);
|
||||||
result[property] = this.flattenSingleKeyObject(obj);
|
list[property] = parsedObj;
|
||||||
} else {
|
|
||||||
result[property] = this.deserializeAndCache(data[property], requestHref);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
console.log(list);
|
||||||
|
Object.assign(object, list);
|
||||||
}
|
}
|
||||||
return result;
|
return object;
|
||||||
}
|
}
|
||||||
|
const result = {};
|
||||||
|
Object.keys(data)
|
||||||
|
.filter((property) => data.hasOwnProperty(property))
|
||||||
|
.filter((property) => hasValue(data[property]))
|
||||||
|
.forEach((property) => {
|
||||||
|
const obj = this.process(data[property], requestHref);
|
||||||
|
result[property] = obj;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected deserializeAndCache<ObjectDomain,ObjectType>(obj, requestHref: string): ObjectDomain[] {
|
protected processPaginatedList<ObjectDomain, ObjectType>(data: any, requestHref: string): PaginatedList<ObjectDomain> {
|
||||||
if (Array.isArray(obj)) {
|
const pageInfo: PageInfo = this.processPageInfo(data);
|
||||||
let result = [];
|
const list = this.flattenSingleKeyObject(data._embedded);
|
||||||
obj.forEach((o) => result = [...result, ...this.deserializeAndCache<ObjectDomain,ObjectType>(o, requestHref)]);
|
const page: ObjectDomain[] = this.processArray(list, requestHref);
|
||||||
return result;
|
return new PaginatedList<ObjectDomain>(pageInfo, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected processArray<ObjectDomain, ObjectType>(data: any, requestHref: string): ObjectDomain[] {
|
||||||
|
let array: ObjectDomain[] = [];
|
||||||
|
data.forEach((datum) => {
|
||||||
|
array = [...array, this.process(datum, requestHref)];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected deserialize<ObjectDomain, ObjectType>(obj, requestHref) {
|
||||||
const type: ObjectType = obj.type;
|
const type: ObjectType = obj.type;
|
||||||
if (hasValue(type)) {
|
if (hasValue(type)) {
|
||||||
const normObjConstructor = this.objectFactory.getConstructor(type) as GenericConstructor<ObjectDomain>;
|
const normObjConstructor = this.objectFactory.getConstructor(type) as GenericConstructor<ObjectDomain>;
|
||||||
|
|
||||||
if (hasValue(normObjConstructor)) {
|
if (hasValue(normObjConstructor)) {
|
||||||
const serializer = new DSpaceRESTv2Serializer(normObjConstructor);
|
const serializer = new DSpaceRESTv2Serializer(normObjConstructor);
|
||||||
|
const res = serializer.deserialize(obj);
|
||||||
let processed;
|
return res;
|
||||||
if (isNotEmpty(obj._embedded)) {
|
|
||||||
processed = this.process<ObjectDomain,ObjectType>(obj._embedded, requestHref);
|
|
||||||
}
|
|
||||||
const normalizedObj: any = serializer.deserialize(obj);
|
|
||||||
|
|
||||||
if (isNotEmpty(processed)) {
|
|
||||||
const processedList = {};
|
|
||||||
Object.keys(processed).forEach((key) => {
|
|
||||||
processedList[key] = processed[key].map((no: NormalizedObject) => (this.toCache) ? no.self : no);
|
|
||||||
});
|
|
||||||
Object.assign(normalizedObj, processedList);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.toCache) {
|
|
||||||
this.addToObjectCache(normalizedObj, requestHref);
|
|
||||||
}
|
|
||||||
return [normalizedObj] as any;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: move check to Validator?
|
// TODO: move check to Validator?
|
||||||
// throw new Error(`The server returned an object with an unknown a known type: ${type}`);
|
// throw new Error(`The server returned an object with an unknown a known type: ${type}`);
|
||||||
return [];
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: move check to Validator
|
// TODO: move check to Validator
|
||||||
// throw new Error(`The server returned an object without a type: ${JSON.stringify(obj)}`);
|
// throw new Error(`The server returned an object without a type: ${JSON.stringify(obj)}`);
|
||||||
return [];
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected cache<ObjectDomain, ObjectType>(obj, requestHref) {
|
||||||
|
if (this.toCache) {
|
||||||
|
this.addToObjectCache(obj, requestHref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +117,7 @@ export abstract class BaseResponseParsingService {
|
|||||||
|
|
||||||
processPageInfo(payload: any): PageInfo {
|
processPageInfo(payload: any): PageInfo {
|
||||||
if (isNotEmpty(payload.page)) {
|
if (isNotEmpty(payload.page)) {
|
||||||
const pageObj = Object.assign({}, payload.page, {_links: payload._links});
|
const pageObj = Object.assign({}, payload.page, { _links: payload._links });
|
||||||
const pageInfoObject = new DSpaceRESTv2Serializer(PageInfo).deserialize(pageObj);
|
const pageInfoObject = new DSpaceRESTv2Serializer(PageInfo).deserialize(pageObj);
|
||||||
if (pageInfoObject.currentPage >= 0) {
|
if (pageInfoObject.currentPage >= 0) {
|
||||||
Object.assign(pageInfoObject, { currentPage: pageInfoObject.currentPage + 1 });
|
Object.assign(pageInfoObject, { currentPage: pageInfoObject.currentPage + 1 });
|
||||||
|
@@ -232,8 +232,11 @@ describe('ConfigResponseParsingService', () => {
|
|||||||
expect(response.constructor).toBe(ErrorResponse);
|
expect(response.constructor).toBe(ErrorResponse);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a ConfigSuccessResponse with the ConfigDefinitions in data', () => {
|
fit('should return a ConfigSuccessResponse with the ConfigDefinitions in data', () => {
|
||||||
const response = service.parse(validRequest, validResponse);
|
const response = service.parse(validRequest, validResponse);
|
||||||
|
debugger;
|
||||||
|
console.log(definitions);
|
||||||
|
console.log((response as any).configDefinition);
|
||||||
expect((response as any).configDefinition).toEqual(definitions);
|
expect((response as any).configDefinition).toEqual(definitions);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -27,9 +27,10 @@ export class ConfigResponseParsingService extends BaseResponseParsingService imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||||
|
console.log(data);
|
||||||
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && data.statusCode === '200') {
|
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && data.statusCode === '200') {
|
||||||
const configDefinition = this.process<ConfigObject,ConfigType>(data.payload, request.href);
|
const configDefinition = this.process<ConfigObject,ConfigType>(data.payload, request.href);
|
||||||
return new ConfigSuccessResponse(configDefinition[Object.keys(configDefinition)[0]], data.statusCode, this.processPageInfo(data.payload));
|
return new ConfigSuccessResponse(configDefinition, data.statusCode, this.processPageInfo(data.payload));
|
||||||
} else {
|
} else {
|
||||||
return new ErrorResponse(
|
return new ErrorResponse(
|
||||||
Object.assign(
|
Object.assign(
|
||||||
|
@@ -12,6 +12,7 @@ import { RestRequest } from './request.models';
|
|||||||
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
import { ResponseParsingService } from './parsing.service';
|
||||||
import { BaseResponseParsingService } from './base-response-parsing.service';
|
import { BaseResponseParsingService } from './base-response-parsing.service';
|
||||||
|
import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
||||||
@@ -27,7 +28,16 @@ export class DSOResponseParsingService extends BaseResponseParsingService implem
|
|||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||||
const processRequestDTO = this.process<NormalizedObject,ResourceType>(data.payload, request.href);
|
const processRequestDTO = this.process<NormalizedObject,ResourceType>(data.payload, request.href);
|
||||||
const selfLinks = this.flattenSingleKeyObject(processRequestDTO).map((no) => no.self);
|
let objectList = processRequestDTO;
|
||||||
|
if (hasNoValue(processRequestDTO)) {
|
||||||
|
return new DSOSuccessResponse(undefined, data.statusCode, undefined)
|
||||||
|
}
|
||||||
|
if (hasValue(processRequestDTO.page)) {
|
||||||
|
objectList = processRequestDTO.page;
|
||||||
|
} else if (!Array.isArray(processRequestDTO)) {
|
||||||
|
objectList = [processRequestDTO];
|
||||||
|
}
|
||||||
|
const selfLinks = objectList.map((no) => no.self);
|
||||||
return new DSOSuccessResponse(selfLinks, data.statusCode, this.processPageInfo(data.payload))
|
return new DSOSuccessResponse(selfLinks, data.statusCode, this.processPageInfo(data.payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,24 +1,25 @@
|
|||||||
|
|
||||||
import { autoserialize } from 'cerialize';
|
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||||
|
import { ResourceType } from './resource-type';
|
||||||
|
|
||||||
export class BitstreamFormat {
|
export class BitstreamFormat implements CacheableObject {
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
shortDescription: string;
|
shortDescription: string;
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
mimetype: string;
|
mimetype: string;
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
supportLevel: number;
|
supportLevel: number;
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
internal: boolean;
|
internal: boolean;
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
extensions: string;
|
extensions: string;
|
||||||
|
|
||||||
|
self: string;
|
||||||
|
|
||||||
|
type: ResourceType;
|
||||||
|
|
||||||
|
uuid: string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ import { Bitstream } from './bitstream.model';
|
|||||||
import { Collection } from './collection.model';
|
import { Collection } from './collection.model';
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
|
|
||||||
export class Community extends DSpaceObject {
|
export class Community extends DSpaceObject {
|
||||||
|
|
||||||
@@ -58,6 +59,6 @@ export class Community extends DSpaceObject {
|
|||||||
*/
|
*/
|
||||||
owner: Observable<RemoteData<Community>>;
|
owner: Observable<RemoteData<Community>>;
|
||||||
|
|
||||||
collections: Observable<RemoteData<Collection[]>>;
|
collections: Observable<RemoteData<PaginatedList<Collection>>>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||||
import { ConfigObject } from './config.model';
|
import { ConfigObject } from './config.model';
|
||||||
import { SubmissionSectionModel } from './config-submission-section.model';
|
import { SubmissionSectionModel } from './config-submission-section.model';
|
||||||
|
import { PaginatedList } from '../../data/paginated-list';
|
||||||
|
|
||||||
@inheritSerialization(ConfigObject)
|
@inheritSerialization(ConfigObject)
|
||||||
export class SubmissionDefinitionsModel extends ConfigObject {
|
export class SubmissionDefinitionsModel extends ConfigObject {
|
||||||
@@ -9,6 +10,6 @@ export class SubmissionDefinitionsModel extends ConfigObject {
|
|||||||
isDefault: boolean;
|
isDefault: boolean;
|
||||||
|
|
||||||
@autoserializeAs(SubmissionSectionModel)
|
@autoserializeAs(SubmissionSectionModel)
|
||||||
sections: SubmissionSectionModel[];
|
sections: PaginatedList<SubmissionSectionModel>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import { Collection } from './collection.model';
|
|||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { Bitstream } from './bitstream.model';
|
import { Bitstream } from './bitstream.model';
|
||||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
|
|
||||||
export class Item extends DSpaceObject {
|
export class Item extends DSpaceObject {
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ export class Item extends DSpaceObject {
|
|||||||
return this.owningCollection;
|
return this.owningCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitstreams: Observable<RemoteData<Bitstream[]>>;
|
bitstreams: Observable<RemoteData<PaginatedList<Bitstream>>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the thumbnail of this item
|
* Retrieves the thumbnail of this item
|
||||||
@@ -88,7 +89,7 @@ export class Item extends DSpaceObject {
|
|||||||
*/
|
*/
|
||||||
getBitstreamsByBundleName(bundleName: string): Observable<Bitstream[]> {
|
getBitstreamsByBundleName(bundleName: string): Observable<Bitstream[]> {
|
||||||
return this.bitstreams
|
return this.bitstreams
|
||||||
.map((rd: RemoteData<Bitstream[]>) => rd.payload)
|
.map((rd: RemoteData<PaginatedList<Bitstream>>) => rd.payload.page)
|
||||||
.filter((bitstreams: Bitstream[]) => hasValue(bitstreams))
|
.filter((bitstreams: Bitstream[]) => hasValue(bitstreams))
|
||||||
.startWith([])
|
.startWith([])
|
||||||
.map((bitstreams) => {
|
.map((bitstreams) => {
|
||||||
|
20
src/app/core/shared/resource-policy.model.ts
Normal file
20
src/app/core/shared/resource-policy.model.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||||
|
import { ResourceType } from './resource-type';
|
||||||
|
|
||||||
|
export class ResourcePolicy implements CacheableObject {
|
||||||
|
|
||||||
|
action: string;
|
||||||
|
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
// TODO group should ofcourse become a group object
|
||||||
|
group: string;
|
||||||
|
|
||||||
|
self: string;
|
||||||
|
|
||||||
|
type: ResourceType;
|
||||||
|
|
||||||
|
uuid: string;
|
||||||
|
|
||||||
|
}
|
@@ -6,4 +6,5 @@ export enum ResourceType {
|
|||||||
Item = 'item',
|
Item = 'item',
|
||||||
Collection = 'collection',
|
Collection = 'collection',
|
||||||
Community = 'community',
|
Community = 'community',
|
||||||
|
ResourcePolicy = 'resourcePolicy'
|
||||||
}
|
}
|
||||||
|
@@ -17,78 +17,86 @@ export const MockItem: Item = Object.assign(new Item(), {
|
|||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
statusCode: '202',
|
statusCode: '202',
|
||||||
pageInfo: {},
|
pageInfo: {},
|
||||||
payload: [
|
payload: {
|
||||||
{
|
pageInfo: {
|
||||||
sizeBytes: 10201,
|
elementsPerPage: 20,
|
||||||
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/content',
|
totalElements: 3,
|
||||||
format: Observable.of({
|
totalPages: 1,
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10',
|
currentPage: 2
|
||||||
requestPending: false,
|
|
||||||
responsePending: false,
|
|
||||||
isSuccessful: true,
|
|
||||||
errorMessage: '',
|
|
||||||
statusCode: '202',
|
|
||||||
pageInfo: {},
|
|
||||||
payload: {
|
|
||||||
shortDescription: 'Microsoft Word XML',
|
|
||||||
description: 'Microsoft Word XML',
|
|
||||||
mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
||||||
supportLevel: 0,
|
|
||||||
internal: false,
|
|
||||||
extensions: null,
|
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10'
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
bundleName: 'ORIGINAL',
|
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
|
||||||
id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
|
||||||
uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
|
||||||
type: 'bitstream',
|
|
||||||
name: 'test_word.docx',
|
|
||||||
metadata: [
|
|
||||||
{
|
|
||||||
key: 'dc.title',
|
|
||||||
language: null,
|
|
||||||
value: 'test_word.docx'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
page: [
|
||||||
sizeBytes: 31302,
|
{
|
||||||
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content',
|
sizeBytes: 10201,
|
||||||
format: Observable.of({
|
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/content',
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4',
|
format: Observable.of({
|
||||||
requestPending: false,
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10',
|
||||||
responsePending: false,
|
requestPending: false,
|
||||||
isSuccessful: true,
|
responsePending: false,
|
||||||
errorMessage: '',
|
isSuccessful: true,
|
||||||
statusCode: '202',
|
errorMessage: '',
|
||||||
pageInfo: {},
|
statusCode: '202',
|
||||||
payload: {
|
pageInfo: {},
|
||||||
shortDescription: 'Adobe PDF',
|
payload: {
|
||||||
description: 'Adobe Portable Document Format',
|
shortDescription: 'Microsoft Word XML',
|
||||||
mimetype: 'application/pdf',
|
description: 'Microsoft Word XML',
|
||||||
supportLevel: 0,
|
mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
internal: false,
|
supportLevel: 0,
|
||||||
extensions: null,
|
internal: false,
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4'
|
extensions: null,
|
||||||
}
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10'
|
||||||
}),
|
}
|
||||||
bundleName: 'ORIGINAL',
|
}),
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28',
|
bundleName: 'ORIGINAL',
|
||||||
id: '99b00f3c-1cc6-4689-8158-91965bee6b28',
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
||||||
uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28',
|
id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
||||||
type: 'bitstream',
|
uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
||||||
name: 'test_pdf.pdf',
|
type: 'bitstream',
|
||||||
metadata: [
|
name: 'test_word.docx',
|
||||||
{
|
metadata: [
|
||||||
key: 'dc.title',
|
{
|
||||||
language: null,
|
key: 'dc.title',
|
||||||
value: 'test_pdf.pdf'
|
language: null,
|
||||||
}
|
value: 'test_word.docx'
|
||||||
]
|
}
|
||||||
}
|
]
|
||||||
]
|
},
|
||||||
|
{
|
||||||
|
sizeBytes: 31302,
|
||||||
|
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content',
|
||||||
|
format: Observable.of({
|
||||||
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4',
|
||||||
|
requestPending: false,
|
||||||
|
responsePending: false,
|
||||||
|
isSuccessful: true,
|
||||||
|
errorMessage: '',
|
||||||
|
statusCode: '202',
|
||||||
|
pageInfo: {},
|
||||||
|
payload: {
|
||||||
|
shortDescription: 'Adobe PDF',
|
||||||
|
description: 'Adobe Portable Document Format',
|
||||||
|
mimetype: 'application/pdf',
|
||||||
|
supportLevel: 0,
|
||||||
|
internal: false,
|
||||||
|
extensions: null,
|
||||||
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
bundleName: 'ORIGINAL',
|
||||||
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28',
|
||||||
|
id: '99b00f3c-1cc6-4689-8158-91965bee6b28',
|
||||||
|
uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28',
|
||||||
|
type: 'bitstream',
|
||||||
|
name: 'test_pdf.pdf',
|
||||||
|
metadata: [
|
||||||
|
{
|
||||||
|
key: 'dc.title',
|
||||||
|
language: null,
|
||||||
|
value: 'test_pdf.pdf'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
||||||
id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
||||||
|
Reference in New Issue
Block a user