From 739371cb35aba8d194b5f60d62970f9d79b7766e Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Thu, 1 Jun 2017 11:41:15 +0200 Subject: [PATCH 01/12] added support for embedded resources --- .../core/cache/builders/build-decorators.ts | 4 +- .../builders/remote-data-build.service.ts | 9 +- .../cache/models/normalized-bundle.model.ts | 6 +- .../models/normalized-collection.model.ts | 4 +- .../models/normalized-community.model.ts | 4 +- .../models/normalized-dspace-object-type.ts | 7 - .../models/normalized-dspace-object.model.ts | 4 +- .../cache/models/normalized-item.model.ts | 6 +- ...actory.ts => normalized-object-factory.ts} | 16 +- src/app/core/cache/response-cache.models.ts | 6 +- src/app/core/data/data.service.ts | 20 +- src/app/core/data/request.effects.ts | 101 ++++- src/app/core/data/request.models.ts | 7 +- src/app/core/data/request.service.ts | 10 +- .../dspace-rest-v2.serializer.spec.ts | 16 +- .../dspace-rest-v2.serializer.ts | 13 +- src/app/core/shared/dspace-object.model.ts | 3 +- src/app/core/shared/resource-type.ts | 11 + src/backend/api.ts | 10 +- src/backend/bitstreams.ts | 92 ++-- src/backend/bundles.ts | 80 ++-- src/backend/collections.ts | 142 +++--- src/backend/communities.ts | 168 +++---- src/backend/items.ts | 421 +++++++++++------- src/backend/metadata.ts | 364 +++++++-------- 25 files changed, 850 insertions(+), 674 deletions(-) delete mode 100644 src/app/core/cache/models/normalized-dspace-object-type.ts rename src/app/core/cache/models/{normalized-dspace-object-factory.ts => normalized-object-factory.ts} (62%) create mode 100644 src/app/core/shared/resource-type.ts diff --git a/src/app/core/cache/builders/build-decorators.ts b/src/app/core/cache/builders/build-decorators.ts index 00cb50663a..f00d8d87e5 100644 --- a/src/app/core/cache/builders/build-decorators.ts +++ b/src/app/core/cache/builders/build-decorators.ts @@ -1,7 +1,7 @@ import "reflect-metadata"; import { GenericConstructor } from "../../shared/generic-constructor"; import { CacheableObject } from "../object-cache.reducer"; -import { NormalizedDSOType } from "../models/normalized-dspace-object-type"; +import { ResourceType } from "../../shared/resource-type"; const mapsToMetadataKey = Symbol("mapsTo"); const relationshipKey = Symbol("relationship"); @@ -16,7 +16,7 @@ export const getMapsTo = function(target: any) { return Reflect.getOwnMetadata(mapsToMetadataKey, target); }; -export const relationship = function(value: NormalizedDSOType): any { +export const relationship = function(value: ResourceType): any { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { if (!target || !propertyKey) { return; diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index f37f0ce4f9..af47b62fe0 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -13,7 +13,8 @@ import { Observable } from "rxjs/Observable"; import { RemoteData } from "../../data/remote-data"; import { GenericConstructor } from "../../shared/generic-constructor"; import { getMapsTo, getResourceType, getRelationships } from "./build-decorators"; -import { NormalizedDSOFactory } from "../models/normalized-dspace-object-factory"; +import { NormalizedObjectFactory } from "../models/normalized-object-factory"; +import { Request } from "../../data/request.models"; @Injectable() export class RemoteDataBuildService { @@ -124,13 +125,13 @@ export class RemoteDataBuildService { relationships.forEach((relationship: string) => { if (hasValue(normalized[relationship])) { const resourceType = getResourceType(normalized, relationship); - const resourceConstructor = NormalizedDSOFactory.getConstructor(resourceType); + const resourceConstructor = NormalizedObjectFactory.getConstructor(resourceType); if (Array.isArray(normalized[relationship])) { // without the setTimeout, the actions inside requestService.configure // are dispatched, but sometimes don't arrive. I'm unsure why atm. setTimeout(() => { normalized[relationship].forEach((href: string) => { - this.requestService.configure(href, resourceConstructor) + this.requestService.configure(new Request(href)) }); }, 0); @@ -142,7 +143,7 @@ export class RemoteDataBuildService { // without the setTimeout, the actions inside requestService.configure // are dispatched, but sometimes don't arrive. I'm unsure why atm. setTimeout(() => { - this.requestService.configure(normalized[relationship], resourceConstructor); + this.requestService.configure(new Request(normalized[relationship])); },0); links[relationship] = this.buildSingle(normalized[relationship], resourceConstructor); diff --git a/src/app/core/cache/models/normalized-bundle.model.ts b/src/app/core/cache/models/normalized-bundle.model.ts index bb0e7b0708..6333428227 100644 --- a/src/app/core/cache/models/normalized-bundle.model.ts +++ b/src/app/core/cache/models/normalized-bundle.model.ts @@ -2,7 +2,7 @@ import { autoserialize, inheritSerialization } from "cerialize"; import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; import { Bundle } from "../../shared/bundle.model"; import { mapsTo, relationship } from "../builders/build-decorators"; -import { NormalizedDSOType } from "./normalized-dspace-object-type"; +import { ResourceType } from "../../shared/resource-type"; @mapsTo(Bundle) @inheritSerialization(NormalizedDSpaceObject) @@ -11,7 +11,7 @@ export class NormalizedBundle extends NormalizedDSpaceObject { * The primary bitstream of this Bundle */ @autoserialize - @relationship(NormalizedDSOType.NormalizedBitstream) + @relationship(ResourceType.Bitstream) primaryBitstream: string; /** @@ -25,6 +25,6 @@ export class NormalizedBundle extends NormalizedDSpaceObject { owner: string; @autoserialize - @relationship(NormalizedDSOType.NormalizedBitstream) + @relationship(ResourceType.Bitstream) bitstreams: Array; } diff --git a/src/app/core/cache/models/normalized-collection.model.ts b/src/app/core/cache/models/normalized-collection.model.ts index 9b31f34837..e0f96ff805 100644 --- a/src/app/core/cache/models/normalized-collection.model.ts +++ b/src/app/core/cache/models/normalized-collection.model.ts @@ -2,7 +2,7 @@ import { autoserialize, inheritSerialization, autoserializeAs } from "cerialize" import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; import { Collection } from "../../shared/collection.model"; import { mapsTo, relationship } from "../builders/build-decorators"; -import { NormalizedDSOType } from "./normalized-dspace-object-type"; +import { ResourceType } from "../../shared/resource-type"; @mapsTo(Collection) @inheritSerialization(NormalizedDSpaceObject) @@ -30,7 +30,7 @@ export class NormalizedCollection extends NormalizedDSpaceObject { owner: string; @autoserialize - @relationship(NormalizedDSOType.NormalizedItem) + @relationship(ResourceType.Item) items: Array; } diff --git a/src/app/core/cache/models/normalized-community.model.ts b/src/app/core/cache/models/normalized-community.model.ts index 774abcc979..f6c971b460 100644 --- a/src/app/core/cache/models/normalized-community.model.ts +++ b/src/app/core/cache/models/normalized-community.model.ts @@ -2,7 +2,7 @@ import { autoserialize, inheritSerialization, autoserializeAs } from "cerialize" import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; import { Community } from "../../shared/community.model"; import { mapsTo, relationship } from "../builders/build-decorators"; -import { NormalizedDSOType } from "./normalized-dspace-object-type"; +import { ResourceType } from "../../shared/resource-type"; @mapsTo(Community) @inheritSerialization(NormalizedDSpaceObject) @@ -30,7 +30,7 @@ export class NormalizedCommunity extends NormalizedDSpaceObject { owner: string; @autoserialize - @relationship(NormalizedDSOType.NormalizedCollection) + @relationship(ResourceType.Collection) collections: Array; } diff --git a/src/app/core/cache/models/normalized-dspace-object-type.ts b/src/app/core/cache/models/normalized-dspace-object-type.ts deleted file mode 100644 index 8ac9215b44..0000000000 --- a/src/app/core/cache/models/normalized-dspace-object-type.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum NormalizedDSOType { - NormalizedBitstream, - NormalizedBundle, - NormalizedItem, - NormalizedCollection, - NormalizedCommunity -} diff --git a/src/app/core/cache/models/normalized-dspace-object.model.ts b/src/app/core/cache/models/normalized-dspace-object.model.ts index 17aa2d3d8c..f4b879c01a 100644 --- a/src/app/core/cache/models/normalized-dspace-object.model.ts +++ b/src/app/core/cache/models/normalized-dspace-object.model.ts @@ -1,6 +1,7 @@ import { autoserialize, autoserializeAs } from "cerialize"; import { CacheableObject } from "../object-cache.reducer"; import { Metadatum } from "../../shared/metadatum.model"; +import { ResourceType } from "../../shared/resource-type"; /** * An abstract model class for a DSpaceObject. @@ -26,7 +27,7 @@ export abstract class NormalizedDSpaceObject implements CacheableObject { * A string representing the kind of DSpaceObject, e.g. community, item, … */ @autoserialize - type: string; + type: ResourceType; /** * The name for this DSpaceObject @@ -49,5 +50,6 @@ export abstract class NormalizedDSpaceObject implements CacheableObject { /** * The DSpaceObject that owns this DSpaceObject */ + @autoserialize owner: string; } diff --git a/src/app/core/cache/models/normalized-item.model.ts b/src/app/core/cache/models/normalized-item.model.ts index cdd3acdb92..15b4822cdf 100644 --- a/src/app/core/cache/models/normalized-item.model.ts +++ b/src/app/core/cache/models/normalized-item.model.ts @@ -2,7 +2,7 @@ import { inheritSerialization, autoserialize } from "cerialize"; import { NormalizedDSpaceObject } from "./normalized-dspace-object.model"; import { Item } from "../../shared/item.model"; import { mapsTo, relationship } from "../builders/build-decorators"; -import { NormalizedDSOType } from "./normalized-dspace-object-type"; +import { ResourceType } from "../../shared/resource-type"; @mapsTo(Item) @inheritSerialization(NormalizedDSpaceObject) @@ -33,7 +33,7 @@ export class NormalizedItem extends NormalizedDSpaceObject { * An array of Collections that are direct parents of this Item */ @autoserialize - @relationship(NormalizedDSOType.NormalizedCollection) + @relationship(ResourceType.Collection) parents: Array; /** @@ -42,6 +42,6 @@ export class NormalizedItem extends NormalizedDSpaceObject { owner: string; @autoserialize - @relationship(NormalizedDSOType.NormalizedBundle) + @relationship(ResourceType.Bundle) bundles: Array; } diff --git a/src/app/core/cache/models/normalized-dspace-object-factory.ts b/src/app/core/cache/models/normalized-object-factory.ts similarity index 62% rename from src/app/core/cache/models/normalized-dspace-object-factory.ts rename to src/app/core/cache/models/normalized-object-factory.ts index 052f7be3ee..45eaacbf5c 100644 --- a/src/app/core/cache/models/normalized-dspace-object-factory.ts +++ b/src/app/core/cache/models/normalized-object-factory.ts @@ -4,25 +4,25 @@ import { NormalizedBundle } from "./normalized-bundle.model"; import { NormalizedItem } from "./normalized-item.model"; import { NormalizedCollection } from "./normalized-collection.model"; import { GenericConstructor } from "../../shared/generic-constructor"; -import { NormalizedDSOType } from "./normalized-dspace-object-type"; import { NormalizedCommunity } from "./normalized-community.model"; +import { ResourceType } from "../../shared/resource-type"; -export class NormalizedDSOFactory { - public static getConstructor(type: NormalizedDSOType): GenericConstructor { +export class NormalizedObjectFactory { + public static getConstructor(type: ResourceType): GenericConstructor { switch (type) { - case NormalizedDSOType.NormalizedBitstream: { + case ResourceType.Bitstream: { return NormalizedBitstream } - case NormalizedDSOType.NormalizedBundle: { + case ResourceType.Bundle: { return NormalizedBundle } - case NormalizedDSOType.NormalizedItem: { + case ResourceType.Item: { return NormalizedItem } - case NormalizedDSOType.NormalizedCollection: { + case ResourceType.Collection: { return NormalizedCollection } - case NormalizedDSOType.NormalizedCommunity: { + case ResourceType.Community: { return NormalizedCommunity } default: { diff --git a/src/app/core/cache/response-cache.models.ts b/src/app/core/cache/response-cache.models.ts index 741acf99a6..4208b4cada 100644 --- a/src/app/core/cache/response-cache.models.ts +++ b/src/app/core/cache/response-cache.models.ts @@ -9,8 +9,12 @@ export class SuccessResponse extends Response { } export class ErrorResponse extends Response { - constructor(public errorMessage: string) { + errorMessage: string; + + constructor(error: Error) { super(false); + console.error(error); + this.errorMessage = error.message; } } diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index 809ff799b3..43db6cc4a2 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -33,11 +33,8 @@ export abstract class DataService findAll(scopeID?: string): RemoteData> { const href = this.getFindAllHref(scopeID); - if (!this.responseCache.has(href) && !this.requestService.isPending(href)) { - const request = new FindAllRequest(href, this.normalizedResourceType, scopeID); - this.store.dispatch(new RequestConfigureAction(request)); - this.store.dispatch(new RequestExecuteAction(href)); - } + const request = new FindAllRequest(href, scopeID); + this.requestService.configure(request); return this.rdbService.buildList(href, this.normalizedResourceType); // return this.rdbService.buildList(href); } @@ -48,21 +45,14 @@ export abstract class DataService findById(id: string): RemoteData { const href = this.getFindByIDHref(id); - if (!this.objectCache.hasBySelfLink(href) && !this.requestService.isPending(href)) { - const request = new FindByIDRequest(href, this.normalizedResourceType, id); - this.store.dispatch(new RequestConfigureAction(request)); - this.store.dispatch(new RequestExecuteAction(href)); - } + const request = new FindByIDRequest(href, id); + this.requestService.configure(request); return this.rdbService.buildSingle(href, this.normalizedResourceType); // return this.rdbService.buildSingle(href); } findByHref(href: string): RemoteData { - if (!this.objectCache.hasBySelfLink(href) && !this.requestService.isPending(href)) { - const request = new Request(href, this.normalizedResourceType); - this.store.dispatch(new RequestConfigureAction(request)); - this.store.dispatch(new RequestExecuteAction(href)); - } + this.requestService.configure(new Request(href)); return this.rdbService.buildSingle(href, this.normalizedResourceType); // return this.rdbService.buildSingle(href)); } diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index e5d887626e..64e7aec1fd 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -8,7 +8,7 @@ import { DSpaceRESTv2Serializer } from "../dspace-rest-v2/dspace-rest-v2.seriali import { CacheableObject } from "../cache/object-cache.reducer"; import { Observable } from "rxjs"; import { Response, SuccessResponse, ErrorResponse } from "../cache/response-cache.models"; -import { hasNoValue } from "../../shared/empty.util"; +import { hasNoValue, hasValue, isEmpty, isNotEmpty } from "../../shared/empty.util"; import { GlobalConfig, GLOBAL_CONFIG } from "../../../config"; import { RequestState, RequestEntry } from "./request.reducer"; import { @@ -17,6 +17,12 @@ import { } from "./request.actions"; 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"; + +function isObjectLevel(halObj: any) { + return isNotEmpty(halObj._links) && hasValue(halObj._links.self); +} @Injectable() export class RequestEffects { @@ -38,30 +44,87 @@ export class RequestEffects { .take(1); }) .flatMap((entry: RequestEntry) => { - const [ifArray, ifNotArray] = this.restApi.get(entry.request.href) - .share() // share ensures restApi.get() doesn't get called twice when the partitions are used below - .partition((data: DSpaceRESTV2Response) => Array.isArray(data._embedded)); - - return Observable.merge( - - ifArray.map((data: DSpaceRESTV2Response) => { - return new DSpaceRESTv2Serializer(entry.request.resourceType).deserializeArray(data); - }).do((cos: CacheableObject[]) => cos.forEach((t) => this.addToObjectCache(t))) - .map((cos: Array): Array => cos.map(t => t.uuid)), - - ifNotArray.map((data: DSpaceRESTV2Response) => { - return new DSpaceRESTv2Serializer(entry.request.resourceType).deserialize(data); - }).do((co: CacheableObject) => this.addToObjectCache(co)) - .map((co: CacheableObject): Array => [co.uuid]) - - ).map((ids: Array) => new SuccessResponse(ids)) + return this.restApi.get(entry.request.href) + .map((data: DSpaceRESTV2Response) => this.processEmbedded(data._embedded)) + .map((ids: Array) => new SuccessResponse(ids)) .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.message)) + .catch((error: Error) => 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 { + + if (isNotEmpty(_embedded)) { + if (isObjectLevel(_embedded)) { + return this.deserializeAndCache(_embedded); + } + else { + let uuids = []; + Object.keys(_embedded) + .filter(property => _embedded.hasOwnProperty(property)) + .forEach(property => { + uuids = [...uuids, ...this.deserializeAndCache(_embedded[property])]; + }); + return uuids; + } + } + } + + protected deserializeAndCache(obj): Array { + let type: ResourceType; + const isArray = Array.isArray(obj); + + if (isArray && isEmpty(obj)) { + return []; + } + + if (isArray) { + type = obj[0]["type"]; + } + else { + type = obj["type"]; + } + + if (hasValue(type)) { + const normObjConstructor = NormalizedObjectFactory.getConstructor(type); + + if (hasValue(normObjConstructor)) { + const serializer = new DSpaceRESTv2Serializer(normObjConstructor); + + if (isArray) { + obj.forEach(o => { + if (isNotEmpty(o._embedded)) { + this.processEmbedded(o._embedded); + } + }); + const normalizedObjArr = serializer.deserializeArray(obj); + normalizedObjArr.forEach(t => this.addToObjectCache(t)); + return normalizedObjArr.map(t => t.uuid); + } + else { + if (isNotEmpty(obj._embedded)) { + this.processEmbedded(obj._embedded); + } + const normalizedObj = serializer.deserialize(obj); + this.addToObjectCache(normalizedObj); + return [normalizedObj.uuid]; + } + + } + else { + //TODO move check to Validator? + throw new Error(`The server returned an object with an unknown a known type: ${type}`); + } + + } + else { + //TODO move check to Validator + throw new Error(`The server returned an object without a type: ${JSON.stringify(obj)}`); + } + } + protected addToObjectCache(co: CacheableObject): void { if (hasNoValue(co) || hasNoValue(co.uuid)) { throw new Error('The server returned an invalid object'); diff --git a/src/app/core/data/request.models.ts b/src/app/core/data/request.models.ts index 9171bbe509..eb74f4b35d 100644 --- a/src/app/core/data/request.models.ts +++ b/src/app/core/data/request.models.ts @@ -5,28 +5,25 @@ import { GenericConstructor } from "../shared/generic-constructor"; export class Request { constructor( public href: string, - public resourceType: GenericConstructor ) {} } export class FindByIDRequest extends Request { constructor( href: string, - resourceType: GenericConstructor, public resourceID: string ) { - super(href, resourceType); + super(href); } } export class FindAllRequest extends Request { constructor( href: string, - resourceType: GenericConstructor, public scopeID?: string, public paginationOptions?: PaginationOptions, public sortOptions?: SortOptions ) { - super(href, resourceType); + super(href); } } diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index b3b28af2c2..35ce8ea078 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -8,7 +8,6 @@ import { RequestConfigureAction, RequestExecuteAction } from "./request.actions" import { ResponseCacheService } from "../cache/response-cache.service"; import { ObjectCacheService } from "../cache/object-cache.service"; import { CacheableObject } from "../cache/object-cache.reducer"; -import { GenericConstructor } from "../shared/generic-constructor"; @Injectable() export class RequestService { @@ -35,14 +34,13 @@ export class RequestService { return this.store.select('core', 'data', 'request', href); } - configure(href: string, normalizedType: GenericConstructor): void { - const isCached = this.objectCache.hasBySelfLink(href); - const isPending = this.isPending(href); + configure(request: Request): void { + const isCached = this.objectCache.hasBySelfLink(request.href); + const isPending = this.isPending(request.href); if (!(isCached || isPending)) { - const request = new Request(href, normalizedType); this.store.dispatch(new RequestConfigureAction(request)); - this.store.dispatch(new RequestExecuteAction(href)); + this.store.dispatch(new RequestExecuteAction(request.href)); } } } diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts index 236244873c..67914c2a92 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.spec.ts @@ -84,14 +84,10 @@ describe("DSpaceRESTv2Serializer", () => { it("should turn a valid document describing a single entity in to a valid model", () => { const serializer = new DSpaceRESTv2Serializer(TestModel); - const doc = { - "_embedded": testResponses[0], - }; + const model = serializer.deserialize(testResponses[0]); - const model = serializer.deserialize(doc); - - expect(model.id).toBe(doc._embedded.id); - expect(model.name).toBe(doc._embedded.name); + expect(model.id).toBe(testResponses[0].id); + expect(model.name).toBe(testResponses[0].name); }); //TODO cant implement/test this yet - depends on how relationships @@ -127,12 +123,8 @@ describe("DSpaceRESTv2Serializer", () => { it("should throw an error when dealing with a document describing an array", () => { const serializer = new DSpaceRESTv2Serializer(TestModel); - const doc = { - "_embedded": testResponses - }; - expect(() => { - serializer.deserialize(doc); + serializer.deserialize(testResponses); }).toThrow(); }); diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts index d4d5a7ce59..b9f1a0be14 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.serializer.ts @@ -3,6 +3,7 @@ import { Serializer } from "../serializer"; import { DSpaceRESTV2Response } from "./dspace-rest-v2-response.model"; import { DSpaceRESTv2Validator } from "./dspace-rest-v2.validator"; import { GenericConstructor } from "../shared/generic-constructor"; +import { hasNoValue, hasValue } from "../../shared/empty.util"; /** * This Serializer turns responses from v2 of DSpace's REST API @@ -49,13 +50,13 @@ export class DSpaceRESTv2Serializer implements Serializer { * @param response An object returned by the backend * @returns a model of type T */ - deserialize(response: DSpaceRESTV2Response): T { + deserialize(response: any): T { // TODO enable validation, once rest data stabilizes // new DSpaceRESTv2Validator(response).validate(); - if (Array.isArray(response._embedded)) { + if (Array.isArray(response)) { throw new Error('Expected a single model, use deserializeArray() instead'); } - let normalized = Object.assign({}, response._embedded, this.normalizeLinks(response._embedded._links)); + let normalized = Object.assign({}, response, this.normalizeLinks(response._links)); return Deserialize(normalized, this.modelType); } @@ -65,13 +66,13 @@ export class DSpaceRESTv2Serializer implements Serializer { * @param response An object returned by the backend * @returns an array of models of type T */ - deserializeArray(response: DSpaceRESTV2Response): Array { + deserializeArray(response: any): Array { //TODO enable validation, once rest data stabilizes // new DSpaceRESTv2Validator(response).validate(); - if (!Array.isArray(response._embedded)) { + if (!Array.isArray(response)) { throw new Error('Expected an Array, use deserialize() instead'); } - let normalized = response._embedded.map((resource) => { + let normalized = response.map((resource) => { return Object.assign({}, resource, this.normalizeLinks(resource._links)); }); diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 7f6e0f5ee2..9609782735 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -2,6 +2,7 @@ import { Metadatum } from "./metadatum.model" import { isEmpty, isNotEmpty } from "../../shared/empty.util"; import { CacheableObject } from "../cache/object-cache.reducer"; import { RemoteData } from "../data/remote-data"; +import { ResourceType } from "./resource-type"; /** * An abstract model class for a DSpaceObject. @@ -23,7 +24,7 @@ export abstract class DSpaceObject implements CacheableObject { /** * A string representing the kind of DSpaceObject, e.g. community, item, … */ - type: string; + type: ResourceType; /** * The name for this DSpaceObject diff --git a/src/app/core/shared/resource-type.ts b/src/app/core/shared/resource-type.ts new file mode 100644 index 0000000000..2e180cba71 --- /dev/null +++ b/src/app/core/shared/resource-type.ts @@ -0,0 +1,11 @@ +/** + * TODO replace with actual string enum after upgrade to TypeScript 2.4: + * https://github.com/Microsoft/TypeScript/pull/15486 + */ +export enum ResourceType { + Bundle = "bundle", + Bitstream = "bitstream", + Item = "item", + Collection = "collection", + Community = "community" +} diff --git a/src/backend/api.ts b/src/backend/api.ts index 2fa94e9c28..4255d5723f 100644 --- a/src/backend/api.ts +++ b/src/backend/api.ts @@ -82,7 +82,7 @@ export function createMockApi() { let id = req.params.community_id; try { req.community_id = id; - req.community = COMMUNITIES.find((community) => { + req.community = COMMUNITIES["communities"].find((community) => { return community.id === id; }); next(); @@ -143,7 +143,7 @@ export function createMockApi() { let id = req.params.collection_id; try { req.collection_id = id; - req.collection = COLLECTIONS.find((collection) => { + req.collection = COLLECTIONS["collections"].find((collection) => { return collection.id === id; }); next(); @@ -205,7 +205,7 @@ export function createMockApi() { let id = req.params.item_id; try { req.item_id = id; - req.item = ITEMS.find((item) => { + req.item = ITEMS["items"].find((item) => { return item.id === id; }); next(); @@ -250,7 +250,7 @@ export function createMockApi() { let id = req.params.bundle_id; try { req.bundle_id = id; - req.bundle = BUNDLES.find((bundle) => { + req.bundle = BUNDLES["bundles"].find((bundle) => { return bundle.id === id; }); next(); @@ -280,7 +280,7 @@ export function createMockApi() { let id = req.params.bitstream_id; try { req.bitstream_id = id; - req.bitstream = BITSTREAMS.find((bitstream) => { + req.bitstream = BITSTREAMS["bitstreams"].find((bitstream) => { return bitstream.id === id; }); next(); diff --git a/src/backend/bitstreams.ts b/src/backend/bitstreams.ts index 6d10f87fbf..537cd5890b 100644 --- a/src/backend/bitstreams.ts +++ b/src/backend/bitstreams.ts @@ -1,46 +1,48 @@ -export const BITSTREAMS = [ - { - "_links": { - "self": { "href": "/bitstreams/3678" }, - "bundle": { "href": "/bundles/35e0606d-5e18-4f9c-aa61-74fc751cc3f9" }, - "retrieve": { "href": "/bitstreams/43c57c2b-206f-4645-8c8f-5f10c84b09fa/retrieve" } +export const BITSTREAMS = { + "bitstreams": [ + { + "_links": { + "self": { "href": "/bitstreams/3678" }, + "bundle": { "href": "/bundles/35e0606d-5e18-4f9c-aa61-74fc751cc3f9" }, + "retrieve": { "href": "/bitstreams/43c57c2b-206f-4645-8c8f-5f10c84b09fa/retrieve" } + }, + "id": "3678", + "uuid": "43c57c2b-206f-4645-8c8f-5f10c84b09fa", + "type": "bitstream", + "name": "do_open_access_CRL.pdf", + "size": 636626, + "checksum": { + "value": "063dfbbbac873aa3fca479b878eccff3", + "algorithm": "MD5" + }, + "metadata": [ + { "key": "dc.title", "value": "do_open_access_CRL.pdf", "language": null }, + { "key": "dc.description", "value": "Conference Paper", "language": "en" } + ], + "format": "Adobe PDF", + "mimetype": "application/pdf" }, - "id": "3678", - "uuid": "43c57c2b-206f-4645-8c8f-5f10c84b09fa", - "type": "bitstream", - "name": "do_open_access_CRL.pdf", - "size": 636626, - "checksum": { - "value": "063dfbbbac873aa3fca479b878eccff3", - "algorithm": "MD5" - }, - "metadata": [ - { "key": "dc.title", "value": "do_open_access_CRL.pdf", "language": null }, - { "key": "dc.description", "value": "Conference Paper", "language": "en" } - ], - "format": "Adobe PDF", - "mimetype": "application/pdf" - }, - { - "_links": { - "self": { "href": "/bitstreams/8842" }, - "bundle": { "href": "/bundles/a469c57a-abcf-45c3-83e4-b187ebd708fd" }, - "retrieve": { "href": "/rest/bitstreams/1a013ecc-fb25-4689-a44f-f1383ad26632/retrieve" } - }, - "id": "8842", - "uuid": "1a013ecc-fb25-4689-a44f-f1383ad26632", - "type": "bitstream", - "name": "do_open_access_CRL.pdf.jpg", - "size": 41183, - "checksum": { - "value": "a8ad475e86f9645c60e13e06f1427814", - "algorithm": "MD5" - }, - "metadata": [ - { "key": "dc.title", "value": "do_open_access_CRL.pdf.jpg", "language": null }, - { "key": "dc.description", "value": "Generated Thumbnail", "language": "en" } - ], - "format": "JPEG", - "mimetype": "image/jpeg" - } -]; + { + "_links": { + "self": { "href": "/bitstreams/8842" }, + "bundle": { "href": "/bundles/a469c57a-abcf-45c3-83e4-b187ebd708fd" }, + "retrieve": { "href": "/rest/bitstreams/1a013ecc-fb25-4689-a44f-f1383ad26632/retrieve" } + }, + "id": "8842", + "uuid": "1a013ecc-fb25-4689-a44f-f1383ad26632", + "type": "bitstream", + "name": "do_open_access_CRL.pdf.jpg", + "size": 41183, + "checksum": { + "value": "a8ad475e86f9645c60e13e06f1427814", + "algorithm": "MD5" + }, + "metadata": [ + { "key": "dc.title", "value": "do_open_access_CRL.pdf.jpg", "language": null }, + { "key": "dc.description", "value": "Generated Thumbnail", "language": "en" } + ], + "format": "JPEG", + "mimetype": "image/jpeg" + } + ] +}; diff --git a/src/backend/bundles.ts b/src/backend/bundles.ts index 678b98007c..5370c1a5a3 100644 --- a/src/backend/bundles.ts +++ b/src/backend/bundles.ts @@ -1,40 +1,42 @@ -export const BUNDLES = [ - { - "_links": { - "self": { "href": "/bundles/2355" }, - "items": [ - { "href": "/items/8871" } - ], - "bitstreams": [ - { "href": "/bitstreams/3678" }, - ], - "primaryBitstream": { "href": "/bitstreams/3678" } +export const BUNDLES = { + "bundles": [ + { + "_links": { + "self": { "href": "/bundles/2355" }, + "items": [ + { "href": "/items/8871" } + ], + "bitstreams": [ + { "href": "/bitstreams/3678" }, + ], + "primaryBitstream": { "href": "/bitstreams/3678" } + }, + "id": "2355", + "uuid": "35e0606d-5e18-4f9c-aa61-74fc751cc3f9", + "type": "bundle", + "name": "ORIGINAL", + "metadata": [ + { "key": "dc.title", "value": "ORIGINAL", "language": "en" } + ] }, - "id": "2355", - "uuid": "35e0606d-5e18-4f9c-aa61-74fc751cc3f9", - "type": "bundle", - "name": "ORIGINAL", - "metadata": [ - { "key": "dc.title", "value": "ORIGINAL", "language": "en" } - ] - }, - { - "_links": { - "self": { "href": "/bundles/5687" }, - "items": [ - { "href": "/items/8871" } - ], - "bitstreams": [ - { "href": "/bitstreams/8842" }, - ], - "primaryBitstream": { "href": "/bitstreams/8842" } - }, - "id": "5687", - "uuid": "a469c57a-abcf-45c3-83e4-b187ebd708fd", - "type": "bundle", - "name": "THUMBNAIL", - "metadata": [ - { "key": "dc.title", "value": "THUMBNAIL", "language": "en" } - ] - } -]; + { + "_links": { + "self": { "href": "/bundles/5687" }, + "items": [ + { "href": "/items/8871" } + ], + "bitstreams": [ + { "href": "/bitstreams/8842" }, + ], + "primaryBitstream": { "href": "/bitstreams/8842" } + }, + "id": "5687", + "uuid": "a469c57a-abcf-45c3-83e4-b187ebd708fd", + "type": "bundle", + "name": "THUMBNAIL", + "metadata": [ + { "key": "dc.title", "value": "THUMBNAIL", "language": "en" } + ] + } + ] +}; diff --git a/src/backend/collections.ts b/src/backend/collections.ts index c701b38ed4..ffc56b0140 100644 --- a/src/backend/collections.ts +++ b/src/backend/collections.ts @@ -1,74 +1,76 @@ -export const COLLECTIONS = [ - { - "_links": { - "self": { "href": "/collections/5179" }, - "items": [ - { "href": "/items/8871" }, - { "href": "/items/9978" } +export const COLLECTIONS = { + "collections": [ + { + "_links": { + "self": { "href": "/collections/5179" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "5179", + "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "type": "collection", + "name": "A Test Collection", + "handle": "123456789/5179", + "metadata": [ + { + "key": "dc.rights", + "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "language": null + }, + { + "key": "dc.description", + "value": "

An introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "A collection for testing purposes", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

Some news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + "language": null + } ] }, - "id": "5179", - "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", - "type": "collection", - "name": "A Test Collection", - "handle": "123456789/5179", - "metadata": [ - { - "key": "dc.rights", - "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", - "language": null + { + "_links": { + "self": { "href": "/collections/6547" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] }, - { - "key": "dc.description", - "value": "

An introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "A collection for testing purposes", - "language": null - }, - { - "key": "dc.description.tableofcontents", - "value": "

Some news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", - "language": null - } - ] - }, - { - "_links": { - "self": { "href": "/collections/6547" }, - "items": [ - { "href": "/items/8871" }, - { "href": "/items/9978" } + "id": "6547", + "uuid": "598ce822-c357-46f3-ab70-63724d02d6ad", + "type": "collection", + "name": "Another Test Collection", + "handle": "123456789/6547", + "metadata": [ + { + "key": "dc.rights", + "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "language": null + }, + { + "key": "dc.description", + "value": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "Another collection for testing purposes", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + "language": null + } ] - }, - "id": "6547", - "uuid": "598ce822-c357-46f3-ab70-63724d02d6ad", - "type": "collection", - "name": "Another Test Collection", - "handle": "123456789/6547", - "metadata": [ - { - "key": "dc.rights", - "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", - "language": null - }, - { - "key": "dc.description", - "value": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "Another collection for testing purposes", - "language": null - }, - { - "key": "dc.description.tableofcontents", - "value": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", - "language": null - } - ] - } -]; + } + ] +}; diff --git a/src/backend/communities.ts b/src/backend/communities.ts index 940f6c72d5..0eea2480ab 100644 --- a/src/backend/communities.ts +++ b/src/backend/communities.ts @@ -1,86 +1,88 @@ -export const COMMUNITIES = [ - { - "name": "Community 1", - "handle": "10673/1", - "id": "6631", - "uuid": "83cd3281-f241-48be-9234-d876f8010d14", - "type": "community", - "metadata": [ - { - "key": "dc.description", - "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "This is a sample top-level community", - "language": null - }, - { - "key": "dc.description.tableofcontents", - "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", - "language": null - }, - { - "key": "dc.rights", - "value": "

If this Community had special copyright text to display, it would be displayed here.

", - "language": null - }, - { - "key": "dc.title", - "value": "Sample Community", - "language": null +export const COMMUNITIES = { + "communities": [ + { + "name": "Community 1", + "handle": "10673/1", + "id": "6631", + "uuid": "83cd3281-f241-48be-9234-d876f8010d14", + "type": "community", + "metadata": [ + { + "key": "dc.description", + "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "This is a sample top-level community", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", + "language": null + }, + { + "key": "dc.rights", + "value": "

If this Community had special copyright text to display, it would be displayed here.

", + "language": null + }, + { + "key": "dc.title", + "value": "Sample Community", + "language": null + } + ], + "_links": { + "self": { + "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" + }, + "collections": [ + { "href": "/collections/5179" } + ] } - ], - "_links": { - "self": { - "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" - }, - "collections": [ - { "href": "/collections/5179" } - ] - } - }, - { - "name": "Community 2", - "handle": "10673/2", - "id": "2365", - "uuid": "80eec4c6-70bd-4beb-b3d4-5d46c6343157", - "type": "community", - "metadata": [ - { - "key": "dc.description", - "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "This is a sample top-level community", - "language": null - }, - { - "key": "dc.description.tableofcontents", - "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", - "language": null - }, - { - "key": "dc.rights", - "value": "

If this Community had special copyright text to display, it would be displayed here.

", - "language": null - }, - { - "key": "dc.title", - "value": "Sample Community", - "language": null + }, + { + "name": "Community 2", + "handle": "10673/2", + "id": "2365", + "uuid": "80eec4c6-70bd-4beb-b3d4-5d46c6343157", + "type": "community", + "metadata": [ + { + "key": "dc.description", + "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "This is a sample top-level community", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", + "language": null + }, + { + "key": "dc.rights", + "value": "

If this Community had special copyright text to display, it would be displayed here.

", + "language": null + }, + { + "key": "dc.title", + "value": "Sample Community", + "language": null + } + ], + "_links": { + "self": { + "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" + }, + "collections": [ + { "href": "/collections/6547" } + ] } - ], - "_links": { - "self": { - "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" - }, - "collections": [ - { "href": "/collections/6547" } - ] } - } -]; + ] +}; diff --git a/src/backend/items.ts b/src/backend/items.ts index 80690132bd..eb69821037 100644 --- a/src/backend/items.ts +++ b/src/backend/items.ts @@ -1,168 +1,281 @@ -export const ITEMS = [ - { - "_links": { - "self": { - "href": "/items/8871" +export const ITEMS = { + "items": [ + { + "_links": { + "self": { + "href": "/items/8871" + }, + "parents": [ + { + "href": "/collections/5179" + }, + { + "href": "/collections/6547" + } + ], + "bundles": [ + { + "href": "/bundles/2355" + }, + // { + // "href": "/bundles/5687" + // } + ] }, - "parents": [ + "id": "8871", + "uuid": "21539b1d-9ef1-4eda-9c77-49565b5bfb78", + "type": "item", + "name": "Do Open-Access Articles Have a Greater Research Impact?", + "handle": "123456789/8871", + "lastModified": "2016-10-14 10:41:12.886", + "isArchived": true, + "isWithdrawn": false, + "metadata": [ { - "href": "/collections/5179" + "key": "dc.contributor.author", + "value": "Antelman, Kristin", + "language": "en" }, { - "href": "/collections/6547" + "key": "dc.date.accessioned", + "value": "2016-10-14T10:41:13Z", + "language": null + }, + { + "key": "dc.date.available", + "value": "2016-10-14T10:41:13Z", + "language": null + }, + { + "key": "dc.date.issued", + "value": "2004-09-01", + "language": "en" + }, + { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/8871", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", + "language": "en" + }, + { + "key": "dc.publisher", + "value": "College & Research Libraries News", + "language": "en" + }, + { + "key": "dc.subject", + "value": "Publishing", + "language": "en" + }, + { + "key": "dc.subject", + "value": "Intellectual Property", + "language": "en" + }, + { + "key": "dc.subject", + "value": "Open Access", + "language": "en" + }, + { + "key": "dc.title", + "value": "Do Open-Access Articles Have a Greater Research Impact?", + "language": "en" + }, + { + "key": "dc.type", + "value": "(not specified)", + "language": "en" } ], - "bundles": [ - { - "href": "/bundles/2355" - }, - // { - // "href": "/bundles/5687" - // } - ] - }, - "id": "8871", - "uuid": "21539b1d-9ef1-4eda-9c77-49565b5bfb78", - "type": "item", - "name": "Do Open-Access Articles Have a Greater Research Impact?", - "handle": "123456789/8871", - "lastModified": "2016-10-14 10:41:12.886", - "isArchived": true, - "isWithdrawn": false, - "metadata": [ - { - "key": "dc.contributor.author", - "value": "Antelman, Kristin", - "language": "en" - }, - { - "key": "dc.date.accessioned", - "value": "2016-10-14T10:41:13Z", - "language": null - }, - { - "key": "dc.date.available", - "value": "2016-10-14T10:41:13Z", - "language": null - }, - { - "key": "dc.date.issued", - "value": "2004-09-01", - "language": "en" - }, - { - "key": "dc.identifier.uri", - "value": "http://hdl.handle.net/123456789/8871", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", - "language": "en" - }, - { - "key": "dc.publisher", - "value": "College & Research Libraries News", - "language": "en" - }, - { - "key": "dc.subject", - "value": "Publishing", - "language": "en" - }, - { - "key": "dc.subject", - "value": "Intellectual Property", - "language": "en" - }, - { - "key": "dc.subject", - "value": "Open Access", - "language": "en" - }, - { - "key": "dc.title", - "value": "Do Open-Access Articles Have a Greater Research Impact?", - "language": "en" - }, - { - "key": "dc.type", - "value": "(not specified)", - "language": "en" + "_embedded": { + "parents": [ + { + "_links": { + "self": { "href": "/collections/5179" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "5179", + "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "type": "collection", + "name": "A Test Collection", + "handle": "123456789/5179", + }, + { + "_links": { + "self": { "href": "/collections/6547" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "6547", + "uuid": "598ce822-c357-46f3-ab70-63724d02d6ad", + "type": "collection", + "name": "Another Test Collection", + "handle": "123456789/6547", + } + ], + "bundles": [ + { + "_links": { + "self": { "href": "/bundles/2355" }, + "items": [ + { "href": "/items/8871" } + ], + "bitstreams": [ + { "href": "/bitstreams/3678" }, + ], + "primaryBitstream": { "href": "/bitstreams/3678" } + }, + "id": "2355", + "uuid": "35e0606d-5e18-4f9c-aa61-74fc751cc3f9", + "type": "bundle", + "name": "ORIGINAL", + "metadata": [ + { "key": "dc.title", "value": "ORIGINAL", "language": "en" } + ], + "_embedded": { + "bitstreams": [ + { + "_links": { + "self": { "href": "/bitstreams/3678" }, + "bundle": { "href": "/bundles/35e0606d-5e18-4f9c-aa61-74fc751cc3f9" }, + "retrieve": { "href": "/bitstreams/43c57c2b-206f-4645-8c8f-5f10c84b09fa/retrieve" } + }, + "id": "3678", + "uuid": "43c57c2b-206f-4645-8c8f-5f10c84b09fa", + "type": "bitstream", + "name": "do_open_access_CRL.pdf", + "size": 636626, + "checksum": { + "value": "063dfbbbac873aa3fca479b878eccff3", + "algorithm": "MD5" + }, + "metadata": [ + { "key": "dc.title", "value": "do_open_access_CRL.pdf", "language": null }, + { "key": "dc.description", "value": "Conference Paper", "language": "en" } + ], + "format": "Adobe PDF", + "mimetype": "application/pdf" + } + ] + } + } + ] } - ] - }, - { - "_links": { - "self": { - "href": "/items/9978" + }, + { + "_links": { + "self": { + "href": "/items/9978" + }, + "parents": [ + { + "href": "/collections/5179" + }, + { + "href": "/collections/6547" + } + ], + "bundles": [ + { + "href": "/bundles/2355" + }, + // { + // "href": "/bundles/5687" + // } + ] }, - "parents": [ + "id": "9978", + "uuid": "be8325f7-243b-49f4-8a4b-df2b793ff3b5", + "type": "item", + "name": "Another Test Item", + "handle": "123456789/9978", + "lastModified": "2016-05-27 03:00:20.063", + "isArchived": true, + "isWithdrawn": false, + "metadata": [ { - "href": "/collections/5179" + "key": "dc.contributor.author", + "value": "John Doe", + "language": "en" }, { - "href": "/collections/6547" + "key": "dc.date.accessioned", + "value": "2016-05-27T07:45:04Z", + "language": null + }, + { + "key": "dc.date.available", + "value": "2016-05-27T07:45:04Z", + "language": null + }, + { + "key": "dc.date.issued", + "value": "2016-05-27", + "language": "en" + }, + { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/9978", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", + "language": "en" + }, + { + "key": "dc.title", + "value": "Another Test Item", + "language": "en" + }, + { + "key": "dc.type", + "value": "(not specified)", + "language": "en" } ], - "bundles": [ - { - "href": "/bundles/2355" - }, - // { - // "href": "/bundles/5687" - // } - ] - }, - "id": "9978", - "uuid": "be8325f7-243b-49f4-8a4b-df2b793ff3b5", - "type": "item", - "name": "Another Test Item", - "handle": "123456789/9978", - "lastModified": "2016-05-27 03:00:20.063", - "isArchived": true, - "isWithdrawn": false, - "metadata": [ - { - "key": "dc.contributor.author", - "value": "John Doe", - "language": "en" - }, - { - "key": "dc.date.accessioned", - "value": "2016-05-27T07:45:04Z", - "language": null - }, - { - "key": "dc.date.available", - "value": "2016-05-27T07:45:04Z", - "language": null - }, - { - "key": "dc.date.issued", - "value": "2016-05-27", - "language": "en" - }, - { - "key": "dc.identifier.uri", - "value": "http://hdl.handle.net/123456789/9978", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", - "language": "en" - }, - { - "key": "dc.title", - "value": "Another Test Item", - "language": "en" - }, - { - "key": "dc.type", - "value": "(not specified)", - "language": "en" + "_embedded": { + "parents": [ + { + "_links": { + "self": { "href": "/collections/5179" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "5179", + "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "type": "collection", + "name": "A Test Collection", + "handle": "123456789/5179", + }, + { + "_links": { + "self": { "href": "/collections/6547" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "6547", + "uuid": "598ce822-c357-46f3-ab70-63724d02d6ad", + "type": "collection", + "name": "Another Test Collection", + "handle": "123456789/6547", + } + ] } - ] - } -]; + } + ] +}; diff --git a/src/backend/metadata.ts b/src/backend/metadata.ts index 68f2ac9f5e..0524b4769e 100644 --- a/src/backend/metadata.ts +++ b/src/backend/metadata.ts @@ -1,182 +1,184 @@ -export const METADATA = [ - { - "type": "metadata", - "id": "d58a3098-b390-4cd6-8f52-b088b3daa637", - "attributes": { - "key": "dc.contributor.author", - "value": "Antelman, Kristin", - "language": "en" +export const METADATA = { + "metadata": [ + { + "type": "metadata", + "id": "d58a3098-b390-4cd6-8f52-b088b3daa637", + "attributes": { + "key": "dc.contributor.author", + "value": "Antelman, Kristin", + "language": "en" + } + }, + { + "type": "metadata", + "id": "56660730-0e0d-47ec-864a-bda2327d5716", + "attributes": { + "key": "dc.date.accessioned", + "value": "2016-10-14T10:41:13Z", + "language": null + } + }, + { + "type": "metadata", + "id": "b9d4ae74-2758-4964-a95e-eecd35b62f26", + "attributes": { + "key": "dc.date.available", + "value": "2016-10-14T10:41:13Z", + "language": null + } + }, + { + "type": "metadata", + "id": "311529ea-e339-4d8f-9292-813ebe515f03", + "attributes": { + "key": "dc.date.issued", + "value": "2004-09-01", + "language": "en" + } + }, + { + "type": "metadata", + "id": "fa875444-3faf-482a-b099-77233bda914d", + "attributes": { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/8871", + "language": null + } + }, + { + "type": "metadata", + "id": "ddbb161b-6e52-4a90-9096-c8eae8cec4c9", + "attributes": { + "key": "dc.description.abstract", + "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", + "language": "en" + } + }, + { + "type": "metadata", + "id": "ba51287d-a2c9-409b-8129-060b693a7570", + "attributes": { + "key": "dc.publisher", + "value": "College & Research Libraries News", + "language": "en" + } + }, + { + "type": "metadata", + "id": "e5c1c9d4-b4e2-4bdc-9153-6b769742b33f", + "attributes": { + "key": "dc.subject", + "value": "Publishing", + "language": "en" + } + }, + { + "type": "metadata", + "id": "4c125844-1eca-47aa-98f8-61c51a9c962f", + "attributes": { + "key": "dc.subject", + "value": "Intellectual Property", + "language": "en" + } + }, + { + "type": "metadata", + "id": "362c753c-a44d-468d-b256-486470b8c1e1", + "attributes": { + "key": "dc.subject", + "value": "Open Access", + "language": "en" + } + }, + { + "type": "metadata", + "id": " 69a02355-37bb-479f-9496-c8743fcacf3c", + "attributes": { + "key": "dc.title", + "value": "Do Open-Access Articles Have a Greater Research Impact?", + "language": "en" + } + }, + { + "type": "metadata", + "id": "ffbd75d5-bf3a-47ff-af22-490240f6fcc6", + "attributes": { + "key": "dc.type", + "value": "(not specified)", + "language": "en" + } + }, + { + "type": "metadata", + "id": "981c725e-53f3-4749-89ee-ef042f23c3c3", + "attributes": { + "key": "dc.contributor.author", + "value": "John Doe", + "language": "en" + } + }, + { + "type": "metadata", + "id": "521df61d-c541-4180-beb8-ac0a1bd1e852", + "attributes": { + "key": "dc.date.accessioned", + "value": "2016-05-27T07:45:04Z", + "language": null + } + }, + { + "type": "metadata", + "id": "551a216d-5350-4b15-9398-9bc2e95e7a3d", + "attributes": { + "key": "dc.date.available", + "value": "2016-05-27T07:45:04Z", + "language": null + } + }, + { + "type": "metadata", + "id": " eb17dce4-3892-47fe-b014-6ff8e17a93ef", + "attributes": { + "key": "dc.date.issued", + "value": "2016-05-27", + "language": "en" + } + }, + { + "type": "metadata", + "id": "3e840957-cb1b-4521-8f5d-fb5f6956f303", + "attributes": { + "key": "dc.identifier.uri", + "value": "http://hdl.handle.net/123456789/9978", + "language": null + } + }, + { + "type": "metadata", + "id": "ae0bc880-481b-4425-aa5b-354b38d24e4f", + "attributes": { + "key": "dc.description.abstract", + "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", + "language": "en" + } + }, + { + "type": "metadata", + "id": "8dc89ac4-d606-4f1a-8524-8f70a6b371de", + "attributes": { + "key": "dc.title", + "value": "Another Test Item", + "language": "en" + } + }, + { + "type": "metadata", + "id": "13185eb9-dc05-4bd7-9c2d-5322a2ac5326", + "attributes": { + "key": "dc.type", + "value": "(not specified)", + "language": "en" + } } - }, - { - "type": "metadata", - "id": "56660730-0e0d-47ec-864a-bda2327d5716", - "attributes": { - "key": "dc.date.accessioned", - "value": "2016-10-14T10:41:13Z", - "language": null - } - }, - { - "type": "metadata", - "id": "b9d4ae74-2758-4964-a95e-eecd35b62f26", - "attributes": { - "key": "dc.date.available", - "value": "2016-10-14T10:41:13Z", - "language": null - } - }, - { - "type": "metadata", - "id": "311529ea-e339-4d8f-9292-813ebe515f03", - "attributes": { - "key": "dc.date.issued", - "value": "2004-09-01", - "language": "en" - } - }, - { - "type": "metadata", - "id": "fa875444-3faf-482a-b099-77233bda914d", - "attributes": { - "key": "dc.identifier.uri", - "value": "http://hdl.handle.net/123456789/8871", - "language": null - } - }, - { - "type": "metadata", - "id": "ddbb161b-6e52-4a90-9096-c8eae8cec4c9", - "attributes": { - "key": "dc.description.abstract", - "value": "Although many authors believe that their work has a greater research impact if it is freely available, studies to demonstrate that impact are few. This study looks at articles in four disciplines at varying stages of adoption of open access—philosophy, political science, electrical and electronic engineering and mathematics—to see whether they have a greater impact as measured by citations in the ISI Web of Science database when their authors make them freely available on the Internet. The finding is that, across all four disciplines, freely available articles do have a greater research impact. Shedding light on this category of open access reveals that scholars in diverse disciplines are adopting open-access practices and being rewarded for it.", - "language": "en" - } - }, - { - "type": "metadata", - "id": "ba51287d-a2c9-409b-8129-060b693a7570", - "attributes": { - "key": "dc.publisher", - "value": "College & Research Libraries News", - "language": "en" - } - }, - { - "type": "metadata", - "id": "e5c1c9d4-b4e2-4bdc-9153-6b769742b33f", - "attributes": { - "key": "dc.subject", - "value": "Publishing", - "language": "en" - } - }, - { - "type": "metadata", - "id": "4c125844-1eca-47aa-98f8-61c51a9c962f", - "attributes": { - "key": "dc.subject", - "value": "Intellectual Property", - "language": "en" - } - }, - { - "type": "metadata", - "id": "362c753c-a44d-468d-b256-486470b8c1e1", - "attributes": { - "key": "dc.subject", - "value": "Open Access", - "language": "en" - } - }, - { - "type": "metadata", - "id": " 69a02355-37bb-479f-9496-c8743fcacf3c", - "attributes": { - "key": "dc.title", - "value": "Do Open-Access Articles Have a Greater Research Impact?", - "language": "en" - } - }, - { - "type": "metadata", - "id": "ffbd75d5-bf3a-47ff-af22-490240f6fcc6", - "attributes": { - "key": "dc.type", - "value": "(not specified)", - "language": "en" - } - }, - { - "type": "metadata", - "id": "981c725e-53f3-4749-89ee-ef042f23c3c3", - "attributes": { - "key": "dc.contributor.author", - "value": "John Doe", - "language": "en" - } - }, - { - "type": "metadata", - "id": "521df61d-c541-4180-beb8-ac0a1bd1e852", - "attributes": { - "key": "dc.date.accessioned", - "value": "2016-05-27T07:45:04Z", - "language": null - } - }, - { - "type": "metadata", - "id": "551a216d-5350-4b15-9398-9bc2e95e7a3d", - "attributes": { - "key": "dc.date.available", - "value": "2016-05-27T07:45:04Z", - "language": null - } - }, - { - "type": "metadata", - "id": " eb17dce4-3892-47fe-b014-6ff8e17a93ef", - "attributes": { - "key": "dc.date.issued", - "value": "2016-05-27", - "language": "en" - } - }, - { - "type": "metadata", - "id": "3e840957-cb1b-4521-8f5d-fb5f6956f303", - "attributes": { - "key": "dc.identifier.uri", - "value": "http://hdl.handle.net/123456789/9978", - "language": null - } - }, - { - "type": "metadata", - "id": "ae0bc880-481b-4425-aa5b-354b38d24e4f", - "attributes": { - "key": "dc.description.abstract", - "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lacus velit, lacinia eu ultrices nec, auctor in sem. Donec interdum convallis ornare. Aliquam et tortor risus. Praesent ut feugiat eros, eu consequat nibh. Morbi id quam eu mi pellentesque consequat vel vitae sem. Praesent sed velit ullamcorper, efficitur odio non, aliquet urna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque eu placerat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla non aliquet mauris. Nulla quis posuere lorem. Pellentesque tempus maximus ipsum ac pretium. Nunc hendrerit tempus sem, vitae luctus erat consectetur vestibulum. Nulla sodales felis in dictum sagittis.\n\nNullam porta magna quis magna vulputate elementum. Pellentesque dictum lorem id nisl tincidunt condimentum. Sed est dolor, dapibus sit amet augue at, malesuada cursus quam. Pellentesque elit felis, malesuada dictum congue tristique, iaculis euismod ligula. Donec dignissim dolor eu lacus pulvinar porttitor. Sed quis semper augue, dictum sollicitudin eros. \n\nMauris congue lectus at turpis viverra scelerisque. Praesent at urna rhoncus, condimentum odio ac, sagittis libero. Nulla aliquam ornare bibendum. Duis quis ornare urna. Suspendisse semper tincidunt neque nec consequat. Sed enim diam, mollis eu neque vitae, lacinia varius risus. Fusce nec sem tempor, efficitur lectus sed, porta sem. Pellentesque sollicitudin ut dui vitae malesuada.", - "language": "en" - } - }, - { - "type": "metadata", - "id": "8dc89ac4-d606-4f1a-8524-8f70a6b371de", - "attributes": { - "key": "dc.title", - "value": "Another Test Item", - "language": "en" - } - }, - { - "type": "metadata", - "id": "13185eb9-dc05-4bd7-9c2d-5322a2ac5326", - "attributes": { - "key": "dc.type", - "value": "(not specified)", - "language": "en" - } - } -]; + ] +}; From 48c3cb4e46316faddff8b53c1111f0cbe06ae465 Mon Sep 17 00:00:00 2001 From: Christian Scheible Date: Fri, 9 Jun 2017 15:04:48 +0200 Subject: [PATCH 02/12] #89 added community home page --- .../community-page-routing.module.ts | 13 +++++++ .../community-page.component.html | 17 +++++++++ .../community-page.component.scss | 1 + .../community-page.component.ts | 35 ++++++++++++++++++ .../community-page/community-page.module.ts | 37 +++++++++++++++++++ .../community-page-copyright.component.html | 3 ++ .../community-page-copyright.component.scss | 1 + .../community-page-copyright.component.ts | 11 ++++++ .../field-wrapper.component.html | 3 ++ .../field-wrapper.component.scss | 1 + .../field-wrapper/field-wrapper.component.ts | 11 ++++++ ...nity-page-introductory-text.component.html | 3 ++ ...nity-page-introductory-text.component.scss | 1 + ...munity-page-introductory-text.component.ts | 11 ++++++ .../community-page-license.component.html | 4 ++ .../community-page-license.component.scss | 1 + .../community-page-license.component.ts | 11 ++++++ .../logo/community-page-logo.component.html | 3 ++ .../logo/community-page-logo.component.scss | 1 + .../logo/community-page-logo.component.ts | 13 +++++++ .../name/community-page-name.component.html | 1 + .../name/community-page-name.component.scss | 1 + .../name/community-page-name.component.ts | 11 ++++++ .../news/community-page-news.component.html | 4 ++ .../news/community-page-news.component.scss | 1 + .../news/community-page-news.component.ts | 11 ++++++ ...ty-page-sub-collection-list.component.html | 11 ++++++ ...ty-page-sub-collection-list.component.scss | 1 + ...nity-page-sub-collection-list.component.ts | 28 ++++++++++++++ 29 files changed, 250 insertions(+) create mode 100644 src/app/community-page/community-page-routing.module.ts create mode 100644 src/app/community-page/community-page.component.html create mode 100644 src/app/community-page/community-page.component.scss create mode 100644 src/app/community-page/community-page.component.ts create mode 100644 src/app/community-page/community-page.module.ts create mode 100644 src/app/community-page/copyright/community-page-copyright.component.html create mode 100644 src/app/community-page/copyright/community-page-copyright.component.scss create mode 100644 src/app/community-page/copyright/community-page-copyright.component.ts create mode 100644 src/app/community-page/field-wrapper/field-wrapper.component.html create mode 100644 src/app/community-page/field-wrapper/field-wrapper.component.scss create mode 100644 src/app/community-page/field-wrapper/field-wrapper.component.ts create mode 100644 src/app/community-page/introductory-text/community-page-introductory-text.component.html create mode 100644 src/app/community-page/introductory-text/community-page-introductory-text.component.scss create mode 100644 src/app/community-page/introductory-text/community-page-introductory-text.component.ts create mode 100644 src/app/community-page/license/community-page-license.component.html create mode 100644 src/app/community-page/license/community-page-license.component.scss create mode 100644 src/app/community-page/license/community-page-license.component.ts create mode 100644 src/app/community-page/logo/community-page-logo.component.html create mode 100644 src/app/community-page/logo/community-page-logo.component.scss create mode 100644 src/app/community-page/logo/community-page-logo.component.ts create mode 100644 src/app/community-page/name/community-page-name.component.html create mode 100644 src/app/community-page/name/community-page-name.component.scss create mode 100644 src/app/community-page/name/community-page-name.component.ts create mode 100644 src/app/community-page/news/community-page-news.component.html create mode 100644 src/app/community-page/news/community-page-news.component.scss create mode 100644 src/app/community-page/news/community-page-news.component.ts create mode 100644 src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html create mode 100644 src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.scss create mode 100644 src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts diff --git a/src/app/community-page/community-page-routing.module.ts b/src/app/community-page/community-page-routing.module.ts new file mode 100644 index 0000000000..40585617f6 --- /dev/null +++ b/src/app/community-page/community-page-routing.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { CommunityPageComponent } from './community-page.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: 'communities/:id', component: CommunityPageComponent } + ]) + ] +}) +export class CommunityPageRoutingModule { } diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html new file mode 100644 index 0000000000..28425e48fe --- /dev/null +++ b/src/app/community-page/community-page.component.html @@ -0,0 +1,17 @@ +
+ + + + + + + + + + + +
diff --git a/src/app/community-page/community-page.component.scss b/src/app/community-page/community-page.component.scss new file mode 100644 index 0000000000..da97dd7a62 --- /dev/null +++ b/src/app/community-page/community-page.component.scss @@ -0,0 +1 @@ +@import '../../styles/variables.scss'; diff --git a/src/app/community-page/community-page.component.ts b/src/app/community-page/community-page.component.ts new file mode 100644 index 0000000000..cfca9659ba --- /dev/null +++ b/src/app/community-page/community-page.component.ts @@ -0,0 +1,35 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; + +import { Community } from "../core/shared/community.model"; +import { Bitstream } from "../core/shared/bitstream.model"; +import { RemoteData } from "../core/data/remote-data"; +import { CommunityDataService } from "../core/data/community-data.service"; + +@Component({ + selector: 'ds-community-page', + styleUrls: ['./community-page.component.css'], + templateUrl: './community-page.component.html', +}) +export class CommunityPageComponent implements OnInit { + communityData: RemoteData; + logoData: RemoteData; + + constructor( + private communityDataService: CommunityDataService, + private route: ActivatedRoute + ) { + this.universalInit(); + } + + ngOnInit(): void { + this.route.params.subscribe((params: Params) => { + this.communityData = this.communityDataService.findById(params['id']) + this.communityData.payload + .subscribe(community => this.logoData = community.logo); + }); + } + + universalInit() { + } +} diff --git a/src/app/community-page/community-page.module.ts b/src/app/community-page/community-page.module.ts new file mode 100644 index 0000000000..f8fb2c57b3 --- /dev/null +++ b/src/app/community-page/community-page.module.ts @@ -0,0 +1,37 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from "@angular/router"; + +import { TranslateModule } from "@ngx-translate/core"; + +import { CommunityPageComponent } from './community-page.component'; +import { FieldWrapperComponent } from './field-wrapper/field-wrapper.component'; +import { CommunityPageNameComponent } from './name/community-page-name.component'; +import { CommunityPageLogoComponent } from './logo/community-page-logo.component'; +import { CommunityPageIntroductoryTextComponent } from './introductory-text/community-page-introductory-text.component'; +import { CommunityPageNewsComponent } from './news/community-page-news.component'; +import { CommunityPageCopyrightComponent } from './copyright/community-page-copyright.component'; +import { CommunityPageLicenseComponent } from './license/community-page-license.component'; +import { CommunityPageSubCollectionListComponent } from './sub-collection-list/community-page-sub-collection-list.component'; +import { CommunityPageRoutingModule } from './community-page-routing.module'; + +@NgModule({ + imports: [ + CommunityPageRoutingModule, + CommonModule, + TranslateModule, + RouterModule, + ], + declarations: [ + CommunityPageComponent, + FieldWrapperComponent, + CommunityPageNameComponent, + CommunityPageLogoComponent, + CommunityPageIntroductoryTextComponent, + CommunityPageNewsComponent, + CommunityPageCopyrightComponent, + CommunityPageLicenseComponent, + CommunityPageSubCollectionListComponent, + ] +}) +export class CommunityPageModule { } diff --git a/src/app/community-page/copyright/community-page-copyright.component.html b/src/app/community-page/copyright/community-page-copyright.component.html new file mode 100644 index 0000000000..987f3cb64a --- /dev/null +++ b/src/app/community-page/copyright/community-page-copyright.component.html @@ -0,0 +1,3 @@ + +

+
\ No newline at end of file diff --git a/src/app/community-page/copyright/community-page-copyright.component.scss b/src/app/community-page/copyright/community-page-copyright.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/copyright/community-page-copyright.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/copyright/community-page-copyright.component.ts b/src/app/community-page/copyright/community-page-copyright.component.ts new file mode 100644 index 0000000000..1639f57db2 --- /dev/null +++ b/src/app/community-page/copyright/community-page-copyright.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-community-page-copyright', + styleUrls: ['./community-page-copyright.component.css'], + templateUrl: './community-page-copyright.component.html', +}) +export class CommunityPageCopyrightComponent { + @Input() copyrightText: String; +} diff --git a/src/app/community-page/field-wrapper/field-wrapper.component.html b/src/app/community-page/field-wrapper/field-wrapper.component.html new file mode 100644 index 0000000000..67e482efa0 --- /dev/null +++ b/src/app/community-page/field-wrapper/field-wrapper.component.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/app/community-page/field-wrapper/field-wrapper.component.scss b/src/app/community-page/field-wrapper/field-wrapper.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/field-wrapper/field-wrapper.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/field-wrapper/field-wrapper.component.ts b/src/app/community-page/field-wrapper/field-wrapper.component.ts new file mode 100644 index 0000000000..c8420661ea --- /dev/null +++ b/src/app/community-page/field-wrapper/field-wrapper.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-field-wrapper', + styleUrls: ['./field-wrapper.component.css'], + templateUrl: './field-wrapper.component.html', +}) +export class FieldWrapperComponent { + @Input() name: String; +} diff --git a/src/app/community-page/introductory-text/community-page-introductory-text.component.html b/src/app/community-page/introductory-text/community-page-introductory-text.component.html new file mode 100644 index 0000000000..8c1f89544a --- /dev/null +++ b/src/app/community-page/introductory-text/community-page-introductory-text.component.html @@ -0,0 +1,3 @@ + +

+
\ No newline at end of file diff --git a/src/app/community-page/introductory-text/community-page-introductory-text.component.scss b/src/app/community-page/introductory-text/community-page-introductory-text.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/introductory-text/community-page-introductory-text.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/introductory-text/community-page-introductory-text.component.ts b/src/app/community-page/introductory-text/community-page-introductory-text.component.ts new file mode 100644 index 0000000000..beee2df466 --- /dev/null +++ b/src/app/community-page/introductory-text/community-page-introductory-text.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-community-page-introductory-text', + styleUrls: ['./community-page-introductory-text.component.css'], + templateUrl: './community-page-introductory-text.component.html', +}) +export class CommunityPageIntroductoryTextComponent { + @Input() introductoryText: String; +} diff --git a/src/app/community-page/license/community-page-license.component.html b/src/app/community-page/license/community-page-license.component.html new file mode 100644 index 0000000000..7bea146194 --- /dev/null +++ b/src/app/community-page/license/community-page-license.component.html @@ -0,0 +1,4 @@ + +

{{ 'community.page.license' | translate }}

+

{{ license }}

+
\ No newline at end of file diff --git a/src/app/community-page/license/community-page-license.component.scss b/src/app/community-page/license/community-page-license.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/license/community-page-license.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/license/community-page-license.component.ts b/src/app/community-page/license/community-page-license.component.ts new file mode 100644 index 0000000000..cf3e8e0661 --- /dev/null +++ b/src/app/community-page/license/community-page-license.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-community-page-license', + styleUrls: ['./community-page-license.component.css'], + templateUrl: './community-page-license.component.html', +}) +export class CommunityPageLicenseComponent { + @Input() license: String; +} diff --git a/src/app/community-page/logo/community-page-logo.component.html b/src/app/community-page/logo/community-page-logo.component.html new file mode 100644 index 0000000000..d5ef5d6311 --- /dev/null +++ b/src/app/community-page/logo/community-page-logo.component.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/app/community-page/logo/community-page-logo.component.scss b/src/app/community-page/logo/community-page-logo.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/logo/community-page-logo.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/logo/community-page-logo.component.ts b/src/app/community-page/logo/community-page-logo.component.ts new file mode 100644 index 0000000000..3610932745 --- /dev/null +++ b/src/app/community-page/logo/community-page-logo.component.ts @@ -0,0 +1,13 @@ +import { Component, Input } from '@angular/core'; + +import { Bitstream } from "../../core/shared/bitstream.model"; + + +@Component({ + selector: 'ds-community-page-logo', + styleUrls: ['./community-page-logo.component.css'], + templateUrl: './community-page-logo.component.html', +}) +export class CommunityPageLogoComponent { + @Input() logo: Bitstream; +} diff --git a/src/app/community-page/name/community-page-name.component.html b/src/app/community-page/name/community-page-name.component.html new file mode 100644 index 0000000000..21f1f65331 --- /dev/null +++ b/src/app/community-page/name/community-page-name.component.html @@ -0,0 +1 @@ +

{{ name }}

\ No newline at end of file diff --git a/src/app/community-page/name/community-page-name.component.scss b/src/app/community-page/name/community-page-name.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/name/community-page-name.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/name/community-page-name.component.ts b/src/app/community-page/name/community-page-name.component.ts new file mode 100644 index 0000000000..f2cbded07c --- /dev/null +++ b/src/app/community-page/name/community-page-name.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-community-page-name', + styleUrls: ['./community-page-name.component.css'], + templateUrl: './community-page-name.component.html', +}) +export class CommunityPageNameComponent { + @Input() name: String; +} diff --git a/src/app/community-page/news/community-page-news.component.html b/src/app/community-page/news/community-page-news.component.html new file mode 100644 index 0000000000..bce01dd378 --- /dev/null +++ b/src/app/community-page/news/community-page-news.component.html @@ -0,0 +1,4 @@ + +

{{ 'community.page.news' | translate }}

+

+
\ No newline at end of file diff --git a/src/app/community-page/news/community-page-news.component.scss b/src/app/community-page/news/community-page-news.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/news/community-page-news.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/news/community-page-news.component.ts b/src/app/community-page/news/community-page-news.component.ts new file mode 100644 index 0000000000..b978d41a55 --- /dev/null +++ b/src/app/community-page/news/community-page-news.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-community-page-news', + styleUrls: ['./community-page-news.component.css'], + templateUrl: './community-page-news.component.html', +}) +export class CommunityPageNewsComponent { + @Input() sidebarText: String; +} diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html new file mode 100644 index 0000000000..f1f05a0467 --- /dev/null +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html @@ -0,0 +1,11 @@ +
+

{{'community.sub-collection-list.head' | translate}}

+ +
diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.scss b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.scss new file mode 100644 index 0000000000..ad84b72f8c --- /dev/null +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts new file mode 100644 index 0000000000..f3c39914ee --- /dev/null +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.ts @@ -0,0 +1,28 @@ +import { Component, OnInit } from '@angular/core'; +import { CollectionDataService } from "../../core/data/collection-data.service"; +import { RemoteData } from "../../core/data/remote-data"; +import { Collection } from "../../core/shared/collection.model"; + + +@Component({ + selector: 'ds-community-page-sub-collection-list', + styleUrls: ['./community-page-sub-collection-list.component.css'], + templateUrl: './community-page-sub-collection-list.component.html', +}) +export class CommunityPageSubCollectionListComponent implements OnInit { + subCollections: RemoteData; + + constructor( + private cds: CollectionDataService + ) { + this.universalInit(); + } + + universalInit() { + + } + + ngOnInit(): void { + this.subCollections = this.cds.findAll(); + } +} From 7e12b33151944eebae4cbb3dbfa51c592a883353 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 9 Jun 2017 18:32:47 +0200 Subject: [PATCH 03/12] fix merge isses --- .../models/normalized-collection.model.ts | 2 +- src/backend/bitstreams.ts | 1 + src/backend/bundles.ts | 1 + src/backend/items.ts | 105 ++++++++++++++++-- 4 files changed, 98 insertions(+), 11 deletions(-) diff --git a/src/app/core/cache/models/normalized-collection.model.ts b/src/app/core/cache/models/normalized-collection.model.ts index 86a1ba177a..2114e4cc43 100644 --- a/src/app/core/cache/models/normalized-collection.model.ts +++ b/src/app/core/cache/models/normalized-collection.model.ts @@ -18,7 +18,7 @@ export class NormalizedCollection extends NormalizedDSpaceObject { * The Bitstream that represents the logo of this Collection */ @autoserialize - @relationship(NormalizedDSOType.NormalizedBitstream) + @relationship(ResourceType.Bitstream) logo: string; /** diff --git a/src/backend/bitstreams.ts b/src/backend/bitstreams.ts index da6a87e042..63eae94a98 100644 --- a/src/backend/bitstreams.ts +++ b/src/backend/bitstreams.ts @@ -52,6 +52,7 @@ export const BITSTREAMS = { }, "id": "8934", "uuid": "ba7d24f2-8fc7-4b8e-b7b6-6c32be1c12a6", + "type": "bitstream", "name": "license.txt", "size": 41183, "checksum": { diff --git a/src/backend/bundles.ts b/src/backend/bundles.ts index b7411c6412..06a38e6fac 100644 --- a/src/backend/bundles.ts +++ b/src/backend/bundles.ts @@ -51,6 +51,7 @@ export const BUNDLES = { }, "id": "8475", "uuid": "99f78e5e-3677-43b0-aaef-cddaa1a49092", + "type": "bundle", "name": "LICENSE", "metadata": [ { "key": "dc.title", "value": "LICENSE", "language": "en" } diff --git a/src/backend/items.ts b/src/backend/items.ts index 63913f8245..9598f334a2 100644 --- a/src/backend/items.ts +++ b/src/backend/items.ts @@ -17,12 +17,9 @@ export const ITEMS = { { "href": "/bundles/2355" }, - { - "href": "/bundles/5687" - }, - { - "href": "/bundles/8475" - } + // { + // "href": "/bundles/5687" + // } ] }, "id": "8871", @@ -94,7 +91,86 @@ export const ITEMS = { "value": "(not specified)", "language": "en" } - ] + ], + "_embedded": { + "parents": [ + { + "_links": { + "self": { "href": "/collections/5179" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "5179", + "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "type": "collection", + "name": "A Test Collection", + "handle": "123456789/5179", + }, + { + "_links": { + "self": { "href": "/collections/6547" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "6547", + "uuid": "598ce822-c357-46f3-ab70-63724d02d6ad", + "type": "collection", + "name": "Another Test Collection", + "handle": "123456789/6547", + } + ], + "bundles": [ + { + "_links": { + "self": { "href": "/bundles/2355" }, + "items": [ + { "href": "/items/8871" } + ], + "bitstreams": [ + { "href": "/bitstreams/3678" }, + ], + "primaryBitstream": { "href": "/bitstreams/3678" } + }, + "id": "2355", + "uuid": "35e0606d-5e18-4f9c-aa61-74fc751cc3f9", + "type": "bundle", + "name": "ORIGINAL", + "metadata": [ + { "key": "dc.title", "value": "ORIGINAL", "language": "en" } + ], + "_embedded": { + "bitstreams": [ + { + "_links": { + "self": { "href": "/bitstreams/3678" }, + "bundle": { "href": "/bundles/35e0606d-5e18-4f9c-aa61-74fc751cc3f9" }, + "retrieve": { "href": "/bitstreams/43c57c2b-206f-4645-8c8f-5f10c84b09fa/retrieve" } + }, + "id": "3678", + "uuid": "43c57c2b-206f-4645-8c8f-5f10c84b09fa", + "type": "bitstream", + "name": "do_open_access_CRL.pdf", + "size": 636626, + "checksum": { + "value": "063dfbbbac873aa3fca479b878eccff3", + "algorithm": "MD5" + }, + "metadata": [ + { "key": "dc.title", "value": "do_open_access_CRL.pdf", "language": null }, + { "key": "dc.description", "value": "Conference Paper", "language": "en" } + ], + "format": "Adobe PDF", + "mimetype": "application/pdf" + } + ] + } + } + ] + } }, { "_links": { @@ -113,9 +189,9 @@ export const ITEMS = { { "href": "/bundles/2355" }, - { - "href": "/bundles/5687" - } + // { + // "href": "/bundles/5687" + // } ] }, "id": "9978", @@ -167,6 +243,15 @@ export const ITEMS = { "value": "(not specified)", "language": "en" } + ], + "_embedded": { + "parents": [ + { + "_links": { + "self": { "href": "/collections/5179" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } ] } ] From 84a3272e5509a0fd18e97c6f0047c94d20a0a44d Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 12 Jun 2017 10:18:27 +0200 Subject: [PATCH 04/12] never push things on a friday night as you're about to leave ;) --- src/backend/items.ts | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/backend/items.ts b/src/backend/items.ts index 9598f334a2..5460cafa81 100644 --- a/src/backend/items.ts +++ b/src/backend/items.ts @@ -94,20 +94,7 @@ export const ITEMS = { ], "_embedded": { "parents": [ - { - "_links": { - "self": { "href": "/collections/5179" }, - "items": [ - { "href": "/items/8871" }, - { "href": "/items/9978" } - ] - }, - "id": "5179", - "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", - "type": "collection", - "name": "A Test Collection", - "handle": "123456789/5179", - }, + { "_links": { "self": { "href": "/collections/6547" }, @@ -252,7 +239,30 @@ export const ITEMS = { "items": [ { "href": "/items/8871" }, { "href": "/items/9978" } - ] + ] + }, + "id": "5179", + "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", + "type": "collection", + "name": "A Test Collection", + "handle": "123456789/5179", + }, + { + "_links": { + "self": { "href": "/collections/6547" }, + "items": [ + { "href": "/items/8871" }, + { "href": "/items/9978" } + ] + }, + "id": "6547", + "uuid": "598ce822-c357-46f3-ab70-63724d02d6ad", + "type": "collection", + "name": "Another Test Collection", + "handle": "123456789/6547", + } + ] + } } ] }; From e3778afd45a8dd080e59fb9c066c6faac246839a Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 12 Jun 2017 16:35:14 +0200 Subject: [PATCH 05/12] Remove matrix URL notation in PaginationComponent --- .../pagination/pagination.component.spec.ts | 4 ++-- .../shared/pagination/pagination.component.ts | 20 ++++++++++--------- src/app/shared/testing/router-stubs.ts | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/app/shared/pagination/pagination.component.spec.ts b/src/app/shared/pagination/pagination.component.spec.ts index b1e1390dd8..3ff6f39609 100644 --- a/src/app/shared/pagination/pagination.component.spec.ts +++ b/src/app/shared/pagination/pagination.component.spec.ts @@ -247,12 +247,12 @@ describe('Pagination component', () => { changePage(testFixture, 3); tick(); - expect(routerStub.navigate).toHaveBeenCalledWith([{pageId: 'test', page: 3, pageSize: 10}]); + expect(routerStub.navigate).toHaveBeenCalledWith([], { queryParams: { pageId: 'test', page: 3, pageSize: 10 } }); expect(paginationComponent.currentPage).toEqual(3); changePageSize(testFixture, '20'); tick(); - expect(routerStub.navigate).toHaveBeenCalledWith([{pageId: 'test', page: 3, pageSize: 20}]); + expect(routerStub.navigate).toHaveBeenCalledWith([], { queryParams: { pageId: 'test', page: 3, pageSize: 20 } }); expect(paginationComponent.pageSize).toEqual(20); })); diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts index 2d5be240bc..0edf2ad35d 100644 --- a/src/app/shared/pagination/pagination.component.ts +++ b/src/app/shared/pagination/pagination.component.ts @@ -57,6 +57,7 @@ export class PaginationComponent implements OnDestroy, OnInit { * Current page. */ public currentPage = 1; + public currentQueryParams = {}; /** * An observable of HostWindowState type @@ -121,14 +122,15 @@ export class PaginationComponent implements OnDestroy, OnInit { this.pageSize = this.paginationOptions.pageSize; this.pageSizeOptions = this.paginationOptions.pageSizeOptions; - this.routeSubscription = this.route.params - .map(params => params) - .subscribe(params => { - if(this.id == params['pageId'] - && (this.paginationOptions.currentPage != params['page'] - || this.paginationOptions.pageSize != params['pageSize']) + this.routeSubscription = this.route.queryParams + .map(queryParams => queryParams) + .subscribe(queryParams => { + this.currentQueryParams = queryParams; + if(this.id == queryParams['pageId'] + && (this.paginationOptions.currentPage != queryParams['page'] + || this.paginationOptions.pageSize != queryParams['pageSize']) ) { - this.validateParams(params['page'], params['pageSize']); + this.validateParams(queryParams['page'], queryParams['pageSize']); } }); this.setShowingDetail(); @@ -162,7 +164,7 @@ export class PaginationComponent implements OnDestroy, OnInit { * The page being navigated to. */ public doPageChange(page: number) { - this.router.navigate([{ pageId: this.id, page: page, pageSize: this.pageSize }]); + this.router.navigate([], { queryParams: Object.assign({}, this.currentQueryParams, { pageId: this.id, page: page, pageSize: this.pageSize }) }); this.currentPage = page; this.setShowingDetail(); this.pageChange.emit(page); @@ -175,7 +177,7 @@ export class PaginationComponent implements OnDestroy, OnInit { * The new page size. */ public setPageSize(pageSize: number) { - this.router.navigate([{ pageId: this.id, page: this.currentPage, pageSize: pageSize }]); + this.router.navigate([], { queryParams: Object.assign({}, this.currentQueryParams, { pageId: this.id, page: this.currentPage, pageSize: pageSize }) }); this.pageSize = pageSize; this.setShowingDetail(); this.pageSizeChange.emit(pageSize); diff --git a/src/app/shared/testing/router-stubs.ts b/src/app/shared/testing/router-stubs.ts index 42a6270aea..4f68678288 100644 --- a/src/app/shared/testing/router-stubs.ts +++ b/src/app/shared/testing/router-stubs.ts @@ -4,7 +4,6 @@ import { BehaviorSubject } from "rxjs"; export class RouterStub { //noinspection TypeScriptUnresolvedFunction navigate = jasmine.createSpy('navigate'); - //navigate1: jasmine.createSpy('navigate'); } export class ActivatedRouteStub { @@ -12,6 +11,7 @@ export class ActivatedRouteStub { // ActivatedRoute.params is Observable private subject = new BehaviorSubject(this.testParams); params = this.subject.asObservable(); + queryParams = this.subject.asObservable(); constructor(params?: Params) { if (params) { From 06f3a4ff905b5f1b366e18df9e22dcf599d8c578 Mon Sep 17 00:00:00 2001 From: Giuseppe Date: Mon, 12 Jun 2017 16:39:52 +0200 Subject: [PATCH 06/12] Create pagination.component.ts --- src/app/shared/pagination/pagination.component.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts index 0edf2ad35d..cb1155f652 100644 --- a/src/app/shared/pagination/pagination.component.ts +++ b/src/app/shared/pagination/pagination.component.ts @@ -57,6 +57,10 @@ export class PaginationComponent implements OnDestroy, OnInit { * Current page. */ public currentPage = 1; + + /** + * Current URL query parameters + */ public currentQueryParams = {}; /** From 3ad3df75689333b29b6969e6a5f296d7410c3c08 Mon Sep 17 00:00:00 2001 From: Christian Scheible Date: Tue, 13 Jun 2017 10:02:49 +0200 Subject: [PATCH 07/12] =?UTF-8?q?Refactored=20community=20and=20collection?= =?UTF-8?q?=20pages=20to=20use=20a=20shared=20component=20for=20most=20of?= =?UTF-8?q?=20the=20content.=20This=20PR=20connect=E2=80=99s=20to=20#89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/i18n/en.json | 9 +++++ src/app/app.module.ts | 2 + .../collection-page.component.html | 33 +++++++++++------ .../collection-page/collection-page.module.ts | 10 +---- .../collection-page-copyright.component.html | 3 -- .../collection-page-copyright.component.ts | 11 ------ ...tion-page-introductory-text.component.html | 3 -- ...tion-page-introductory-text.component.scss | 1 - ...ection-page-introductory-text.component.ts | 11 ------ .../collection-page-license.component.html | 4 -- .../collection-page-license.component.scss | 1 - .../collection-page-license.component.ts | 11 ------ .../news/collection-page-news.component.html | 4 -- .../news/collection-page-news.component.scss | 1 - .../news/collection-page-news.component.ts | 11 ------ .../community-page.component.html | 33 +++++++++++------ .../community-page/community-page.module.ts | 10 +---- .../community-page-copyright.component.html | 3 -- .../community-page-copyright.component.scss | 1 - .../community-page-copyright.component.ts | 11 ------ ...nity-page-introductory-text.component.html | 3 -- ...nity-page-introductory-text.component.scss | 1 - ...munity-page-introductory-text.component.ts | 11 ------ .../community-page-license.component.html | 4 -- .../community-page-license.component.scss | 1 - .../community-page-license.component.ts | 11 ------ .../news/community-page-news.component.html | 4 -- .../news/community-page-news.component.scss | 1 - .../news/community-page-news.component.ts | 11 ------ .../models/normalized-community.model.ts | 2 + ...content-with-optional-title.component.html | 5 +++ ...ontent-with-optional-title.component.scss} | 0 .../content-with-optional-title.component.ts | 37 +++++++++++++++++++ src/app/shared/shared.module.ts | 4 +- src/backend/communities.ts | 3 +- src/server.routes.ts | 2 +- 36 files changed, 107 insertions(+), 166 deletions(-) delete mode 100644 src/app/collection-page/copyright/collection-page-copyright.component.html delete mode 100644 src/app/collection-page/copyright/collection-page-copyright.component.ts delete mode 100644 src/app/collection-page/introductory-text/collection-page-introductory-text.component.html delete mode 100644 src/app/collection-page/introductory-text/collection-page-introductory-text.component.scss delete mode 100644 src/app/collection-page/introductory-text/collection-page-introductory-text.component.ts delete mode 100644 src/app/collection-page/license/collection-page-license.component.html delete mode 100644 src/app/collection-page/license/collection-page-license.component.scss delete mode 100644 src/app/collection-page/license/collection-page-license.component.ts delete mode 100644 src/app/collection-page/news/collection-page-news.component.html delete mode 100644 src/app/collection-page/news/collection-page-news.component.scss delete mode 100644 src/app/collection-page/news/collection-page-news.component.ts delete mode 100644 src/app/community-page/copyright/community-page-copyright.component.html delete mode 100644 src/app/community-page/copyright/community-page-copyright.component.scss delete mode 100644 src/app/community-page/copyright/community-page-copyright.component.ts delete mode 100644 src/app/community-page/introductory-text/community-page-introductory-text.component.html delete mode 100644 src/app/community-page/introductory-text/community-page-introductory-text.component.scss delete mode 100644 src/app/community-page/introductory-text/community-page-introductory-text.component.ts delete mode 100644 src/app/community-page/license/community-page-license.component.html delete mode 100644 src/app/community-page/license/community-page-license.component.scss delete mode 100644 src/app/community-page/license/community-page-license.component.ts delete mode 100644 src/app/community-page/news/community-page-news.component.html delete mode 100644 src/app/community-page/news/community-page-news.component.scss delete mode 100644 src/app/community-page/news/community-page-news.component.ts create mode 100644 src/app/shared/content-with-optional-title/content-with-optional-title.component.html rename src/app/{collection-page/copyright/collection-page-copyright.component.scss => shared/content-with-optional-title/content-with-optional-title.component.scss} (100%) create mode 100644 src/app/shared/content-with-optional-title/content-with-optional-title.component.ts diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 7489228eb5..82a51f2ebd 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -10,6 +10,15 @@ "license": "License" } }, + "community": { + "page": { + "news": "News", + "license": "License" + }, + "sub-collection-list": { + "head": "Collections of this Community" + } + }, "item": { "page": { "author": "Author", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 95bfc73517..8a20dee66d 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -10,6 +10,7 @@ import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HeaderComponent } from './header/header.component'; import { CollectionPageModule } from './collection-page/collection-page.module'; +import { CommunityPageModule } from './community-page/community-page.module'; import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component'; @@ -24,6 +25,7 @@ import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component'; HomeModule, ItemPageModule, CollectionPageModule, + CommunityPageModule, CoreModule.forRoot(), AppRoutingModule ], diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index e9a4ab9916..cfa4ef4dee 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -1,16 +1,25 @@
- - - - - - - - + + + + + + + + > + + + > +
diff --git a/src/app/collection-page/collection-page.module.ts b/src/app/collection-page/collection-page.module.ts index 9b204cb0bb..1065d237df 100644 --- a/src/app/collection-page/collection-page.module.ts +++ b/src/app/collection-page/collection-page.module.ts @@ -3,14 +3,11 @@ import { CommonModule } from '@angular/common'; import { TranslateModule } from "@ngx-translate/core"; +import { SharedModule } from '../shared/shared.module'; import { CollectionPageComponent } from './collection-page.component'; import { FieldWrapperComponent } from './field-wrapper/field-wrapper.component'; import { CollectionPageNameComponent } from './name/collection-page-name.component'; import { CollectionPageLogoComponent } from './logo/collection-page-logo.component'; -import { CollectionPageIntroductoryTextComponent } from './introductory-text/collection-page-introductory-text.component'; -import { CollectionPageNewsComponent } from './news/collection-page-news.component'; -import { CollectionPageCopyrightComponent } from './copyright/collection-page-copyright.component'; -import { CollectionPageLicenseComponent } from './license/collection-page-license.component'; import { CollectionPageRoutingModule } from './collection-page-routing.module'; @NgModule({ @@ -18,16 +15,13 @@ import { CollectionPageRoutingModule } from './collection-page-routing.module'; CollectionPageRoutingModule, CommonModule, TranslateModule, + SharedModule, ], declarations: [ CollectionPageComponent, FieldWrapperComponent, CollectionPageNameComponent, CollectionPageLogoComponent, - CollectionPageIntroductoryTextComponent, - CollectionPageNewsComponent, - CollectionPageCopyrightComponent, - CollectionPageLicenseComponent, ] }) export class CollectionPageModule { } diff --git a/src/app/collection-page/copyright/collection-page-copyright.component.html b/src/app/collection-page/copyright/collection-page-copyright.component.html deleted file mode 100644 index db7b77d614..0000000000 --- a/src/app/collection-page/copyright/collection-page-copyright.component.html +++ /dev/null @@ -1,3 +0,0 @@ - -

-
\ No newline at end of file diff --git a/src/app/collection-page/copyright/collection-page-copyright.component.ts b/src/app/collection-page/copyright/collection-page-copyright.component.ts deleted file mode 100644 index e4bc21553f..0000000000 --- a/src/app/collection-page/copyright/collection-page-copyright.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-collection-page-copyright', - styleUrls: ['./collection-page-copyright.component.css'], - templateUrl: './collection-page-copyright.component.html', -}) -export class CollectionPageCopyrightComponent { - @Input() copyrightText: String; -} diff --git a/src/app/collection-page/introductory-text/collection-page-introductory-text.component.html b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.html deleted file mode 100644 index 904a6d7f21..0000000000 --- a/src/app/collection-page/introductory-text/collection-page-introductory-text.component.html +++ /dev/null @@ -1,3 +0,0 @@ - -

-
\ No newline at end of file diff --git a/src/app/collection-page/introductory-text/collection-page-introductory-text.component.scss b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/collection-page/introductory-text/collection-page-introductory-text.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/collection-page/introductory-text/collection-page-introductory-text.component.ts b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.ts deleted file mode 100644 index f6526c9943..0000000000 --- a/src/app/collection-page/introductory-text/collection-page-introductory-text.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-collection-page-introductory-text', - styleUrls: ['./collection-page-introductory-text.component.css'], - templateUrl: './collection-page-introductory-text.component.html', -}) -export class CollectionPageIntroductoryTextComponent { - @Input() introductoryText: String; -} diff --git a/src/app/collection-page/license/collection-page-license.component.html b/src/app/collection-page/license/collection-page-license.component.html deleted file mode 100644 index af0a6e4261..0000000000 --- a/src/app/collection-page/license/collection-page-license.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -

{{ 'collection.page.license' | translate }}

-

{{ license }}

-
\ No newline at end of file diff --git a/src/app/collection-page/license/collection-page-license.component.scss b/src/app/collection-page/license/collection-page-license.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/collection-page/license/collection-page-license.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/collection-page/license/collection-page-license.component.ts b/src/app/collection-page/license/collection-page-license.component.ts deleted file mode 100644 index 8f269cca8c..0000000000 --- a/src/app/collection-page/license/collection-page-license.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-collection-page-license', - styleUrls: ['./collection-page-license.component.css'], - templateUrl: './collection-page-license.component.html', -}) -export class CollectionPageLicenseComponent { - @Input() license: String; -} diff --git a/src/app/collection-page/news/collection-page-news.component.html b/src/app/collection-page/news/collection-page-news.component.html deleted file mode 100644 index bd17c7ea77..0000000000 --- a/src/app/collection-page/news/collection-page-news.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -

{{ 'collection.page.news' | translate }}

-

-
\ No newline at end of file diff --git a/src/app/collection-page/news/collection-page-news.component.scss b/src/app/collection-page/news/collection-page-news.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/collection-page/news/collection-page-news.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/collection-page/news/collection-page-news.component.ts b/src/app/collection-page/news/collection-page-news.component.ts deleted file mode 100644 index 479c37a7c6..0000000000 --- a/src/app/collection-page/news/collection-page-news.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-collection-page-news', - styleUrls: ['./collection-page-news.component.css'], - templateUrl: './collection-page-news.component.html', -}) -export class CollectionPageNewsComponent { - @Input() sidebarText: String; -} diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index 28425e48fe..d01130a006 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -1,17 +1,26 @@
- - - - - - - - + + + + + + + + + + + +
diff --git a/src/app/community-page/community-page.module.ts b/src/app/community-page/community-page.module.ts index f8fb2c57b3..043b5ca47a 100644 --- a/src/app/community-page/community-page.module.ts +++ b/src/app/community-page/community-page.module.ts @@ -4,14 +4,11 @@ import { RouterModule } from "@angular/router"; import { TranslateModule } from "@ngx-translate/core"; +import { SharedModule } from '../shared/shared.module'; import { CommunityPageComponent } from './community-page.component'; import { FieldWrapperComponent } from './field-wrapper/field-wrapper.component'; import { CommunityPageNameComponent } from './name/community-page-name.component'; import { CommunityPageLogoComponent } from './logo/community-page-logo.component'; -import { CommunityPageIntroductoryTextComponent } from './introductory-text/community-page-introductory-text.component'; -import { CommunityPageNewsComponent } from './news/community-page-news.component'; -import { CommunityPageCopyrightComponent } from './copyright/community-page-copyright.component'; -import { CommunityPageLicenseComponent } from './license/community-page-license.component'; import { CommunityPageSubCollectionListComponent } from './sub-collection-list/community-page-sub-collection-list.component'; import { CommunityPageRoutingModule } from './community-page-routing.module'; @@ -21,16 +18,13 @@ import { CommunityPageRoutingModule } from './community-page-routing.module'; CommonModule, TranslateModule, RouterModule, + SharedModule, ], declarations: [ CommunityPageComponent, FieldWrapperComponent, CommunityPageNameComponent, CommunityPageLogoComponent, - CommunityPageIntroductoryTextComponent, - CommunityPageNewsComponent, - CommunityPageCopyrightComponent, - CommunityPageLicenseComponent, CommunityPageSubCollectionListComponent, ] }) diff --git a/src/app/community-page/copyright/community-page-copyright.component.html b/src/app/community-page/copyright/community-page-copyright.component.html deleted file mode 100644 index 987f3cb64a..0000000000 --- a/src/app/community-page/copyright/community-page-copyright.component.html +++ /dev/null @@ -1,3 +0,0 @@ - -

-
\ No newline at end of file diff --git a/src/app/community-page/copyright/community-page-copyright.component.scss b/src/app/community-page/copyright/community-page-copyright.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/community-page/copyright/community-page-copyright.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/copyright/community-page-copyright.component.ts b/src/app/community-page/copyright/community-page-copyright.component.ts deleted file mode 100644 index 1639f57db2..0000000000 --- a/src/app/community-page/copyright/community-page-copyright.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-community-page-copyright', - styleUrls: ['./community-page-copyright.component.css'], - templateUrl: './community-page-copyright.component.html', -}) -export class CommunityPageCopyrightComponent { - @Input() copyrightText: String; -} diff --git a/src/app/community-page/introductory-text/community-page-introductory-text.component.html b/src/app/community-page/introductory-text/community-page-introductory-text.component.html deleted file mode 100644 index 8c1f89544a..0000000000 --- a/src/app/community-page/introductory-text/community-page-introductory-text.component.html +++ /dev/null @@ -1,3 +0,0 @@ - -

-
\ No newline at end of file diff --git a/src/app/community-page/introductory-text/community-page-introductory-text.component.scss b/src/app/community-page/introductory-text/community-page-introductory-text.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/community-page/introductory-text/community-page-introductory-text.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/introductory-text/community-page-introductory-text.component.ts b/src/app/community-page/introductory-text/community-page-introductory-text.component.ts deleted file mode 100644 index beee2df466..0000000000 --- a/src/app/community-page/introductory-text/community-page-introductory-text.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-community-page-introductory-text', - styleUrls: ['./community-page-introductory-text.component.css'], - templateUrl: './community-page-introductory-text.component.html', -}) -export class CommunityPageIntroductoryTextComponent { - @Input() introductoryText: String; -} diff --git a/src/app/community-page/license/community-page-license.component.html b/src/app/community-page/license/community-page-license.component.html deleted file mode 100644 index 7bea146194..0000000000 --- a/src/app/community-page/license/community-page-license.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -

{{ 'community.page.license' | translate }}

-

{{ license }}

-
\ No newline at end of file diff --git a/src/app/community-page/license/community-page-license.component.scss b/src/app/community-page/license/community-page-license.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/community-page/license/community-page-license.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/license/community-page-license.component.ts b/src/app/community-page/license/community-page-license.component.ts deleted file mode 100644 index cf3e8e0661..0000000000 --- a/src/app/community-page/license/community-page-license.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-community-page-license', - styleUrls: ['./community-page-license.component.css'], - templateUrl: './community-page-license.component.html', -}) -export class CommunityPageLicenseComponent { - @Input() license: String; -} diff --git a/src/app/community-page/news/community-page-news.component.html b/src/app/community-page/news/community-page-news.component.html deleted file mode 100644 index bce01dd378..0000000000 --- a/src/app/community-page/news/community-page-news.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -

{{ 'community.page.news' | translate }}

-

-
\ No newline at end of file diff --git a/src/app/community-page/news/community-page-news.component.scss b/src/app/community-page/news/community-page-news.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/community-page/news/community-page-news.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/news/community-page-news.component.ts b/src/app/community-page/news/community-page-news.component.ts deleted file mode 100644 index b978d41a55..0000000000 --- a/src/app/community-page/news/community-page-news.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-community-page-news', - styleUrls: ['./community-page-news.component.css'], - templateUrl: './community-page-news.component.html', -}) -export class CommunityPageNewsComponent { - @Input() sidebarText: String; -} diff --git a/src/app/core/cache/models/normalized-community.model.ts b/src/app/core/cache/models/normalized-community.model.ts index 774abcc979..e691f30fec 100644 --- a/src/app/core/cache/models/normalized-community.model.ts +++ b/src/app/core/cache/models/normalized-community.model.ts @@ -17,6 +17,8 @@ export class NormalizedCommunity extends NormalizedDSpaceObject { /** * The Bitstream that represents the logo of this Community */ + @autoserialize + @relationship(NormalizedDSOType.NormalizedBitstream) logo: string; /** diff --git a/src/app/shared/content-with-optional-title/content-with-optional-title.component.html b/src/app/shared/content-with-optional-title/content-with-optional-title.component.html new file mode 100644 index 0000000000..67c49496ae --- /dev/null +++ b/src/app/shared/content-with-optional-title/content-with-optional-title.component.html @@ -0,0 +1,5 @@ +
+

{{ title | translate }}

+

+

{{content}}

+
\ No newline at end of file diff --git a/src/app/collection-page/copyright/collection-page-copyright.component.scss b/src/app/shared/content-with-optional-title/content-with-optional-title.component.scss similarity index 100% rename from src/app/collection-page/copyright/collection-page-copyright.component.scss rename to src/app/shared/content-with-optional-title/content-with-optional-title.component.scss diff --git a/src/app/shared/content-with-optional-title/content-with-optional-title.component.ts b/src/app/shared/content-with-optional-title/content-with-optional-title.component.ts new file mode 100644 index 0000000000..a838f548d8 --- /dev/null +++ b/src/app/shared/content-with-optional-title/content-with-optional-title.component.ts @@ -0,0 +1,37 @@ +import { Component, Input } from '@angular/core'; + +/** + * This component renders any content inside of this component. + * If there is a title set it will render the title. + * If hasInnerHtml is true the content will be handled as html. + * To see how it is used see collection-page or community-page. + */ + +@Component({ + selector: 'ds-content-with-optional-title', + styleUrls: ['./content-with-optional-title.component.css'], + templateUrl: './content-with-optional-title.component.html' +}) +export class ContentWithOptionalTitleComponent { + + // Optional title + @Input() title: string; + + // The content to render. Might be html + @Input() content: string; + + // flag whether the content contains html syntax or not + @Input() hasInnerHtml: boolean; + + + + constructor() { + this.universalInit(); + + } + + universalInit() { + + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 6f93a0b86e..285f1087bd 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -14,6 +14,7 @@ import { ThumbnailComponent } from "../thumbnail/thumbnail.component"; import { SafeUrlPipe } from "./utils/safe-url-pipe"; import { HostWindowService } from "./host-window.service"; import { NativeWindowFactory, NativeWindowService } from "./window.service"; +import { ContentWithOptionalTitleComponent } from "./content-with-optional-title/content-with-optional-title.component"; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -35,7 +36,8 @@ const PIPES = [ const COMPONENTS = [ // put shared components here PaginationComponent, - ThumbnailComponent + ThumbnailComponent, + ContentWithOptionalTitleComponent ]; const PROVIDERS = [ diff --git a/src/backend/communities.ts b/src/backend/communities.ts index 940f6c72d5..02f474f66b 100644 --- a/src/backend/communities.ts +++ b/src/backend/communities.ts @@ -38,7 +38,8 @@ export const COMMUNITIES = [ }, "collections": [ { "href": "/collections/5179" } - ] + ], + "logo": { "href": "/bitstreams/4688" } } }, { diff --git a/src/server.routes.ts b/src/server.routes.ts index 19ba0264aa..834923da30 100644 --- a/src/server.routes.ts +++ b/src/server.routes.ts @@ -10,5 +10,5 @@ * ]; **/ export const routes: string[] = [ - 'home', 'items/:id' , 'collections/:id', '**' + 'home', 'items/:id' , 'collections/:id', 'communities/:id', '**' ]; From 90840d949bea45ad8c8e5a879d96d52a89b132e8 Mon Sep 17 00:00:00 2001 From: Christian Scheible Date: Tue, 13 Jun 2017 14:35:57 +0200 Subject: [PATCH 08/12] Refactored collection/community logo and name as shared components. --- .../collection-page.component.html | 9 +++++++-- .../collection-page/collection-page.module.ts | 4 ---- .../logo/collection-page-logo.component.html | 3 --- .../logo/collection-page-logo.component.ts | 13 ------------- .../name/collection-page-name.component.ts | 11 ----------- .../community-page/community-page.component.html | 16 ++++++++-------- src/app/community-page/community-page.module.ts | 4 ---- .../logo/community-page-logo.component.html | 3 --- .../logo/community-page-logo.component.scss | 1 - .../logo/community-page-logo.component.ts | 13 ------------- .../name/community-page-name.component.html | 1 - .../name/community-page-name.component.scss | 1 - .../name/community-page-name.component.ts | 11 ----------- .../content-with-optional-title.component.html | 4 ++-- src/app/shared/dso-logo/dso-logo.component.html | 3 +++ .../dso-logo/dso-logo.component.scss} | 0 src/app/shared/dso-logo/dso-logo.component.ts | 15 +++++++++++++++ .../dso-name/dso-name.component.html} | 0 .../dso-name/dso-name.component.scss} | 0 src/app/shared/dso-name/dso-name.component.ts | 11 +++++++++++ src/app/shared/shared.module.ts | 6 +++++- 21 files changed, 51 insertions(+), 78 deletions(-) delete mode 100644 src/app/collection-page/logo/collection-page-logo.component.html delete mode 100644 src/app/collection-page/logo/collection-page-logo.component.ts delete mode 100644 src/app/collection-page/name/collection-page-name.component.ts delete mode 100644 src/app/community-page/logo/community-page-logo.component.html delete mode 100644 src/app/community-page/logo/community-page-logo.component.scss delete mode 100644 src/app/community-page/logo/community-page-logo.component.ts delete mode 100644 src/app/community-page/name/community-page-name.component.html delete mode 100644 src/app/community-page/name/community-page-name.component.scss delete mode 100644 src/app/community-page/name/community-page-name.component.ts create mode 100644 src/app/shared/dso-logo/dso-logo.component.html rename src/app/{collection-page/logo/collection-page-logo.component.scss => shared/dso-logo/dso-logo.component.scss} (100%) create mode 100644 src/app/shared/dso-logo/dso-logo.component.ts rename src/app/{collection-page/name/collection-page-name.component.html => shared/dso-name/dso-name.component.html} (100%) rename src/app/{collection-page/name/collection-page-name.component.scss => shared/dso-name/dso-name.component.scss} (100%) create mode 100644 src/app/shared/dso-name/dso-name.component.ts diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index cfa4ef4dee..02fc1fd9b7 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -1,6 +1,11 @@
- - + + + + + - Collection logo - \ No newline at end of file diff --git a/src/app/collection-page/logo/collection-page-logo.component.ts b/src/app/collection-page/logo/collection-page-logo.component.ts deleted file mode 100644 index 22c34422ea..0000000000 --- a/src/app/collection-page/logo/collection-page-logo.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { Bitstream } from "../../core/shared/bitstream.model"; - - -@Component({ - selector: 'ds-collection-page-logo', - styleUrls: ['./collection-page-logo.component.css'], - templateUrl: './collection-page-logo.component.html', -}) -export class CollectionPageLogoComponent { - @Input() logo: Bitstream; -} diff --git a/src/app/collection-page/name/collection-page-name.component.ts b/src/app/collection-page/name/collection-page-name.component.ts deleted file mode 100644 index 30121fd01b..0000000000 --- a/src/app/collection-page/name/collection-page-name.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-collection-page-name', - styleUrls: ['./collection-page-name.component.css'], - templateUrl: './collection-page-name.component.html', -}) -export class CollectionPageNameComponent { - @Input() name: String; -} diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index d01130a006..4fc21b07df 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -1,6 +1,11 @@
- - + + + + + - - - - +
diff --git a/src/app/community-page/community-page.module.ts b/src/app/community-page/community-page.module.ts index 043b5ca47a..0d6db23d32 100644 --- a/src/app/community-page/community-page.module.ts +++ b/src/app/community-page/community-page.module.ts @@ -7,8 +7,6 @@ import { TranslateModule } from "@ngx-translate/core"; import { SharedModule } from '../shared/shared.module'; import { CommunityPageComponent } from './community-page.component'; import { FieldWrapperComponent } from './field-wrapper/field-wrapper.component'; -import { CommunityPageNameComponent } from './name/community-page-name.component'; -import { CommunityPageLogoComponent } from './logo/community-page-logo.component'; import { CommunityPageSubCollectionListComponent } from './sub-collection-list/community-page-sub-collection-list.component'; import { CommunityPageRoutingModule } from './community-page-routing.module'; @@ -23,8 +21,6 @@ import { CommunityPageRoutingModule } from './community-page-routing.module'; declarations: [ CommunityPageComponent, FieldWrapperComponent, - CommunityPageNameComponent, - CommunityPageLogoComponent, CommunityPageSubCollectionListComponent, ] }) diff --git a/src/app/community-page/logo/community-page-logo.component.html b/src/app/community-page/logo/community-page-logo.component.html deleted file mode 100644 index d5ef5d6311..0000000000 --- a/src/app/community-page/logo/community-page-logo.component.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/src/app/community-page/logo/community-page-logo.component.scss b/src/app/community-page/logo/community-page-logo.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/community-page/logo/community-page-logo.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/logo/community-page-logo.component.ts b/src/app/community-page/logo/community-page-logo.component.ts deleted file mode 100644 index 3610932745..0000000000 --- a/src/app/community-page/logo/community-page-logo.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { Bitstream } from "../../core/shared/bitstream.model"; - - -@Component({ - selector: 'ds-community-page-logo', - styleUrls: ['./community-page-logo.component.css'], - templateUrl: './community-page-logo.component.html', -}) -export class CommunityPageLogoComponent { - @Input() logo: Bitstream; -} diff --git a/src/app/community-page/name/community-page-name.component.html b/src/app/community-page/name/community-page-name.component.html deleted file mode 100644 index 21f1f65331..0000000000 --- a/src/app/community-page/name/community-page-name.component.html +++ /dev/null @@ -1 +0,0 @@ -

{{ name }}

\ No newline at end of file diff --git a/src/app/community-page/name/community-page-name.component.scss b/src/app/community-page/name/community-page-name.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/community-page/name/community-page-name.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/community-page/name/community-page-name.component.ts b/src/app/community-page/name/community-page-name.component.ts deleted file mode 100644 index f2cbded07c..0000000000 --- a/src/app/community-page/name/community-page-name.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-community-page-name', - styleUrls: ['./community-page-name.component.css'], - templateUrl: './community-page-name.component.html', -}) -export class CommunityPageNameComponent { - @Input() name: String; -} diff --git a/src/app/shared/content-with-optional-title/content-with-optional-title.component.html b/src/app/shared/content-with-optional-title/content-with-optional-title.component.html index 67c49496ae..4a0be8cfc7 100644 --- a/src/app/shared/content-with-optional-title/content-with-optional-title.component.html +++ b/src/app/shared/content-with-optional-title/content-with-optional-title.component.html @@ -1,5 +1,5 @@

{{ title | translate }}

-

-

{{content}}

+
+
{{content}}
\ No newline at end of file diff --git a/src/app/shared/dso-logo/dso-logo.component.html b/src/app/shared/dso-logo/dso-logo.component.html new file mode 100644 index 0000000000..81769c3c0f --- /dev/null +++ b/src/app/shared/dso-logo/dso-logo.component.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/app/collection-page/logo/collection-page-logo.component.scss b/src/app/shared/dso-logo/dso-logo.component.scss similarity index 100% rename from src/app/collection-page/logo/collection-page-logo.component.scss rename to src/app/shared/dso-logo/dso-logo.component.scss diff --git a/src/app/shared/dso-logo/dso-logo.component.ts b/src/app/shared/dso-logo/dso-logo.component.ts new file mode 100644 index 0000000000..fc41315415 --- /dev/null +++ b/src/app/shared/dso-logo/dso-logo.component.ts @@ -0,0 +1,15 @@ +import { Component, Input } from '@angular/core'; + +import { Bitstream } from "../../core/shared/bitstream.model"; + + +@Component({ + selector: 'ds-dso-logo', + styleUrls: ['./dso-logo.component.css'], + templateUrl: './dso-logo.component.html', +}) +export class DsoLogoComponent { + @Input() logo: Bitstream; + + @Input() alternateText: string; +} \ No newline at end of file diff --git a/src/app/collection-page/name/collection-page-name.component.html b/src/app/shared/dso-name/dso-name.component.html similarity index 100% rename from src/app/collection-page/name/collection-page-name.component.html rename to src/app/shared/dso-name/dso-name.component.html diff --git a/src/app/collection-page/name/collection-page-name.component.scss b/src/app/shared/dso-name/dso-name.component.scss similarity index 100% rename from src/app/collection-page/name/collection-page-name.component.scss rename to src/app/shared/dso-name/dso-name.component.scss diff --git a/src/app/shared/dso-name/dso-name.component.ts b/src/app/shared/dso-name/dso-name.component.ts new file mode 100644 index 0000000000..7f88e3189e --- /dev/null +++ b/src/app/shared/dso-name/dso-name.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-dso-name', + styleUrls: ['./dso-name.component.css'], + templateUrl: './dso-name.component.html', +}) +export class DsoNameComponent { + @Input() name: String; +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 285f1087bd..338fb5fe5d 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -15,6 +15,8 @@ import { SafeUrlPipe } from "./utils/safe-url-pipe"; import { HostWindowService } from "./host-window.service"; import { NativeWindowFactory, NativeWindowService } from "./window.service"; import { ContentWithOptionalTitleComponent } from "./content-with-optional-title/content-with-optional-title.component"; +import { DsoNameComponent } from "./dso-name/dso-name.component"; +import { DsoLogoComponent } from "./dso-logo/dso-logo.component"; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -37,7 +39,9 @@ const COMPONENTS = [ // put shared components here PaginationComponent, ThumbnailComponent, - ContentWithOptionalTitleComponent + ContentWithOptionalTitleComponent, + DsoNameComponent, + DsoLogoComponent ]; const PROVIDERS = [ From ac7b2775e4065e0de99e2f8e0bf481e8124afb1b Mon Sep 17 00:00:00 2001 From: Christian Scheible Date: Tue, 13 Jun 2017 15:41:38 +0200 Subject: [PATCH 09/12] Renamed Collection/Community shared components --- .../collection-page.component.html | 24 ++++++++++--------- .../collection-page/collection-page.module.ts | 2 -- .../field-wrapper.component.html | 3 --- .../field-wrapper/field-wrapper.component.ts | 11 --------- .../community-page.component.html | 18 +++++++------- .../community-page/community-page.module.ts | 2 -- .../field-wrapper.component.html | 3 --- .../field-wrapper/field-wrapper.component.ts | 11 --------- .../comcol-page-content.component.html} | 0 .../comcol-page-content.component.scss} | 0 .../comcol-page-content.component.ts} | 8 +++---- .../comcol-page-header.component.html} | 0 .../comcol-page-header.component.scss} | 0 .../comcol-page-header.component.ts | 11 +++++++++ .../comcol-page-logo.component.html} | 0 .../comcol-page-logo.component.scss} | 0 .../comcol-page-logo.component.ts} | 8 +++---- .../shared/dso-logo/dso-logo.component.scss | 1 - .../shared/dso-name/dso-name.component.scss | 1 - src/app/shared/dso-name/dso-name.component.ts | 11 --------- src/app/shared/shared.module.ts | 12 +++++----- 21 files changed, 47 insertions(+), 79 deletions(-) delete mode 100644 src/app/collection-page/field-wrapper/field-wrapper.component.html delete mode 100644 src/app/collection-page/field-wrapper/field-wrapper.component.ts delete mode 100644 src/app/community-page/field-wrapper/field-wrapper.component.html delete mode 100644 src/app/community-page/field-wrapper/field-wrapper.component.ts rename src/app/shared/{content-with-optional-title/content-with-optional-title.component.html => comcol-page-content/comcol-page-content.component.html} (100%) rename src/app/{collection-page/field-wrapper/field-wrapper.component.scss => shared/comcol-page-content/comcol-page-content.component.scss} (100%) rename src/app/shared/{content-with-optional-title/content-with-optional-title.component.ts => comcol-page-content/comcol-page-content.component.ts} (73%) rename src/app/shared/{dso-name/dso-name.component.html => comcol-page-header/comcol-page-header.component.html} (100%) rename src/app/{community-page/field-wrapper/field-wrapper.component.scss => shared/comcol-page-header/comcol-page-header.component.scss} (100%) create mode 100644 src/app/shared/comcol-page-header/comcol-page-header.component.ts rename src/app/shared/{dso-logo/dso-logo.component.html => comcol-page-logo/comcol-page-logo.component.html} (100%) rename src/app/shared/{content-with-optional-title/content-with-optional-title.component.scss => comcol-page-logo/comcol-page-logo.component.scss} (100%) rename src/app/shared/{dso-logo/dso-logo.component.ts => comcol-page-logo/comcol-page-logo.component.ts} (52%) delete mode 100644 src/app/shared/dso-logo/dso-logo.component.scss delete mode 100644 src/app/shared/dso-name/dso-name.component.scss delete mode 100644 src/app/shared/dso-name/dso-name.component.ts diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index 02fc1fd9b7..f8bfdbc5de 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -1,30 +1,32 @@
- + + - - + - - + - - + - > - + - > - +
diff --git a/src/app/collection-page/collection-page.module.ts b/src/app/collection-page/collection-page.module.ts index 76e3128871..0dfe33fd5a 100644 --- a/src/app/collection-page/collection-page.module.ts +++ b/src/app/collection-page/collection-page.module.ts @@ -5,7 +5,6 @@ import { TranslateModule } from "@ngx-translate/core"; import { SharedModule } from '../shared/shared.module'; import { CollectionPageComponent } from './collection-page.component'; -import { FieldWrapperComponent } from './field-wrapper/field-wrapper.component'; import { CollectionPageRoutingModule } from './collection-page-routing.module'; @NgModule({ @@ -17,7 +16,6 @@ import { CollectionPageRoutingModule } from './collection-page-routing.module'; ], declarations: [ CollectionPageComponent, - FieldWrapperComponent, ] }) export class CollectionPageModule { } diff --git a/src/app/collection-page/field-wrapper/field-wrapper.component.html b/src/app/collection-page/field-wrapper/field-wrapper.component.html deleted file mode 100644 index 677ff2f918..0000000000 --- a/src/app/collection-page/field-wrapper/field-wrapper.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
\ No newline at end of file diff --git a/src/app/collection-page/field-wrapper/field-wrapper.component.ts b/src/app/collection-page/field-wrapper/field-wrapper.component.ts deleted file mode 100644 index c8420661ea..0000000000 --- a/src/app/collection-page/field-wrapper/field-wrapper.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-field-wrapper', - styleUrls: ['./field-wrapper.component.css'], - templateUrl: './field-wrapper.component.html', -}) -export class FieldWrapperComponent { - @Input() name: String; -} diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index 4fc21b07df..83f6a54033 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -1,26 +1,26 @@
- + - - + - - + - - + - - +
diff --git a/src/app/community-page/community-page.module.ts b/src/app/community-page/community-page.module.ts index 0d6db23d32..1410e786b7 100644 --- a/src/app/community-page/community-page.module.ts +++ b/src/app/community-page/community-page.module.ts @@ -6,7 +6,6 @@ import { TranslateModule } from "@ngx-translate/core"; import { SharedModule } from '../shared/shared.module'; import { CommunityPageComponent } from './community-page.component'; -import { FieldWrapperComponent } from './field-wrapper/field-wrapper.component'; import { CommunityPageSubCollectionListComponent } from './sub-collection-list/community-page-sub-collection-list.component'; import { CommunityPageRoutingModule } from './community-page-routing.module'; @@ -20,7 +19,6 @@ import { CommunityPageRoutingModule } from './community-page-routing.module'; ], declarations: [ CommunityPageComponent, - FieldWrapperComponent, CommunityPageSubCollectionListComponent, ] }) diff --git a/src/app/community-page/field-wrapper/field-wrapper.component.html b/src/app/community-page/field-wrapper/field-wrapper.component.html deleted file mode 100644 index 67e482efa0..0000000000 --- a/src/app/community-page/field-wrapper/field-wrapper.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
\ No newline at end of file diff --git a/src/app/community-page/field-wrapper/field-wrapper.component.ts b/src/app/community-page/field-wrapper/field-wrapper.component.ts deleted file mode 100644 index c8420661ea..0000000000 --- a/src/app/community-page/field-wrapper/field-wrapper.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-field-wrapper', - styleUrls: ['./field-wrapper.component.css'], - templateUrl: './field-wrapper.component.html', -}) -export class FieldWrapperComponent { - @Input() name: String; -} diff --git a/src/app/shared/content-with-optional-title/content-with-optional-title.component.html b/src/app/shared/comcol-page-content/comcol-page-content.component.html similarity index 100% rename from src/app/shared/content-with-optional-title/content-with-optional-title.component.html rename to src/app/shared/comcol-page-content/comcol-page-content.component.html diff --git a/src/app/collection-page/field-wrapper/field-wrapper.component.scss b/src/app/shared/comcol-page-content/comcol-page-content.component.scss similarity index 100% rename from src/app/collection-page/field-wrapper/field-wrapper.component.scss rename to src/app/shared/comcol-page-content/comcol-page-content.component.scss diff --git a/src/app/shared/content-with-optional-title/content-with-optional-title.component.ts b/src/app/shared/comcol-page-content/comcol-page-content.component.ts similarity index 73% rename from src/app/shared/content-with-optional-title/content-with-optional-title.component.ts rename to src/app/shared/comcol-page-content/comcol-page-content.component.ts index a838f548d8..da679d31b2 100644 --- a/src/app/shared/content-with-optional-title/content-with-optional-title.component.ts +++ b/src/app/shared/comcol-page-content/comcol-page-content.component.ts @@ -8,11 +8,11 @@ import { Component, Input } from '@angular/core'; */ @Component({ - selector: 'ds-content-with-optional-title', - styleUrls: ['./content-with-optional-title.component.css'], - templateUrl: './content-with-optional-title.component.html' + selector: 'ds-comcol-page-content', + styleUrls: ['./comcol-page-content.component.css'], + templateUrl: './comcol-page-content.component.html' }) -export class ContentWithOptionalTitleComponent { +export class ComcolPageContentComponent { // Optional title @Input() title: string; diff --git a/src/app/shared/dso-name/dso-name.component.html b/src/app/shared/comcol-page-header/comcol-page-header.component.html similarity index 100% rename from src/app/shared/dso-name/dso-name.component.html rename to src/app/shared/comcol-page-header/comcol-page-header.component.html diff --git a/src/app/community-page/field-wrapper/field-wrapper.component.scss b/src/app/shared/comcol-page-header/comcol-page-header.component.scss similarity index 100% rename from src/app/community-page/field-wrapper/field-wrapper.component.scss rename to src/app/shared/comcol-page-header/comcol-page-header.component.scss diff --git a/src/app/shared/comcol-page-header/comcol-page-header.component.ts b/src/app/shared/comcol-page-header/comcol-page-header.component.ts new file mode 100644 index 0000000000..f6578ace29 --- /dev/null +++ b/src/app/shared/comcol-page-header/comcol-page-header.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + + +@Component({ + selector: 'ds-comcol-page-header', + styleUrls: ['./comcol-page-header.component.css'], + templateUrl: './comcol-page-header.component.html', +}) +export class ComcolPageHeaderComponent { + @Input() name: String; +} diff --git a/src/app/shared/dso-logo/dso-logo.component.html b/src/app/shared/comcol-page-logo/comcol-page-logo.component.html similarity index 100% rename from src/app/shared/dso-logo/dso-logo.component.html rename to src/app/shared/comcol-page-logo/comcol-page-logo.component.html diff --git a/src/app/shared/content-with-optional-title/content-with-optional-title.component.scss b/src/app/shared/comcol-page-logo/comcol-page-logo.component.scss similarity index 100% rename from src/app/shared/content-with-optional-title/content-with-optional-title.component.scss rename to src/app/shared/comcol-page-logo/comcol-page-logo.component.scss diff --git a/src/app/shared/dso-logo/dso-logo.component.ts b/src/app/shared/comcol-page-logo/comcol-page-logo.component.ts similarity index 52% rename from src/app/shared/dso-logo/dso-logo.component.ts rename to src/app/shared/comcol-page-logo/comcol-page-logo.component.ts index fc41315415..87239e3a11 100644 --- a/src/app/shared/dso-logo/dso-logo.component.ts +++ b/src/app/shared/comcol-page-logo/comcol-page-logo.component.ts @@ -4,11 +4,11 @@ import { Bitstream } from "../../core/shared/bitstream.model"; @Component({ - selector: 'ds-dso-logo', - styleUrls: ['./dso-logo.component.css'], - templateUrl: './dso-logo.component.html', + selector: 'ds-comcol-page-logo', + styleUrls: ['./comcol-page-logo.component.css'], + templateUrl: './comcol-page-logo.component.html', }) -export class DsoLogoComponent { +export class ComcolPageLogoComponent { @Input() logo: Bitstream; @Input() alternateText: string; diff --git a/src/app/shared/dso-logo/dso-logo.component.scss b/src/app/shared/dso-logo/dso-logo.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/shared/dso-logo/dso-logo.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/shared/dso-name/dso-name.component.scss b/src/app/shared/dso-name/dso-name.component.scss deleted file mode 100644 index ad84b72f8c..0000000000 --- a/src/app/shared/dso-name/dso-name.component.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../../styles/variables.scss'; \ No newline at end of file diff --git a/src/app/shared/dso-name/dso-name.component.ts b/src/app/shared/dso-name/dso-name.component.ts deleted file mode 100644 index 7f88e3189e..0000000000 --- a/src/app/shared/dso-name/dso-name.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - - -@Component({ - selector: 'ds-dso-name', - styleUrls: ['./dso-name.component.css'], - templateUrl: './dso-name.component.html', -}) -export class DsoNameComponent { - @Input() name: String; -} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 338fb5fe5d..817ae5f26e 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -14,9 +14,9 @@ import { ThumbnailComponent } from "../thumbnail/thumbnail.component"; import { SafeUrlPipe } from "./utils/safe-url-pipe"; import { HostWindowService } from "./host-window.service"; import { NativeWindowFactory, NativeWindowService } from "./window.service"; -import { ContentWithOptionalTitleComponent } from "./content-with-optional-title/content-with-optional-title.component"; -import { DsoNameComponent } from "./dso-name/dso-name.component"; -import { DsoLogoComponent } from "./dso-logo/dso-logo.component"; +import { ComcolPageContentComponent } from "./comcol-page-content/comcol-page-content.component"; +import { ComcolPageHeaderComponent } from "./comcol-page-header/comcol-page-header.component"; +import { ComcolPageLogoComponent } from "./comcol-page-logo/comcol-page-logo.component"; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -39,9 +39,9 @@ const COMPONENTS = [ // put shared components here PaginationComponent, ThumbnailComponent, - ContentWithOptionalTitleComponent, - DsoNameComponent, - DsoLogoComponent + ComcolPageContentComponent, + ComcolPageHeaderComponent, + ComcolPageLogoComponent ]; const PROVIDERS = [ From c6494d3de3110c4790ffe25ba919a4021168832a Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 16 Jun 2017 10:44:49 +0200 Subject: [PATCH 10/12] fixed an issue where incomplete mock data caused an error on collection homepages --- .../collection-page.component.ts | 16 +++-- src/backend/items.ts | 70 ++++++++++++++++++- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/app/collection-page/collection-page.component.ts b/src/app/collection-page/collection-page.component.ts index 42afe78881..a7148cbc74 100644 --- a/src/app/collection-page/collection-page.component.ts +++ b/src/app/collection-page/collection-page.component.ts @@ -1,19 +1,21 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; import { Collection } from "../core/shared/collection.model"; import { Bitstream } from "../core/shared/bitstream.model"; import { RemoteData } from "../core/data/remote-data"; import { CollectionDataService } from "../core/data/collection-data.service"; +import { Subscription } from "rxjs/Subscription"; @Component({ selector: 'ds-collection-page', styleUrls: ['./collection-page.component.css'], templateUrl: './collection-page.component.html', }) -export class CollectionPageComponent implements OnInit { +export class CollectionPageComponent implements OnInit, OnDestroy { collectionData: RemoteData; logoData: RemoteData; + private subs: Subscription[] = []; constructor( private collectionDataService: CollectionDataService, @@ -24,12 +26,16 @@ export class CollectionPageComponent implements OnInit { ngOnInit(): void { this.route.params.subscribe((params: Params) => { - this.collectionData = this.collectionDataService.findById(params['id']) - this.collectionData.payload - .subscribe(collection => this.logoData = collection.logo); + this.collectionData = this.collectionDataService.findById(params['id']); + this.subs.push(this.collectionData.payload + .subscribe(collection => this.logoData = collection.logo)); }); } + ngOnDestroy(): void { + this.subs.forEach(sub => sub.unsubscribe()); + } + universalInit() { } } diff --git a/src/backend/items.ts b/src/backend/items.ts index 5460cafa81..45d71fa092 100644 --- a/src/backend/items.ts +++ b/src/backend/items.ts @@ -94,7 +94,6 @@ export const ITEMS = { ], "_embedded": { "parents": [ - { "_links": { "self": { "href": "/collections/6547" }, @@ -108,6 +107,28 @@ export const ITEMS = { "type": "collection", "name": "Another Test Collection", "handle": "123456789/6547", + "metadata": [ + { + "key": "dc.rights", + "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "language": null + }, + { + "key": "dc.description", + "value": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "Another collection for testing purposes", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + "language": null + } + ] } ], "bundles": [ @@ -239,13 +260,36 @@ export const ITEMS = { "items": [ { "href": "/items/8871" }, { "href": "/items/9978" } - ] + ], + "logo": { "href": "/bitstreams/4688" } }, "id": "5179", "uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60", "type": "collection", "name": "A Test Collection", "handle": "123456789/5179", + "metadata": [ + { + "key": "dc.rights", + "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "language": null + }, + { + "key": "dc.description", + "value": "

An introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "A collection for testing purposes", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

Some news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + "language": null + } + ] }, { "_links": { @@ -260,6 +304,28 @@ export const ITEMS = { "type": "collection", "name": "Another Test Collection", "handle": "123456789/6547", + "metadata": [ + { + "key": "dc.rights", + "value": "

© 2005-2016 JOHN DOE SOME RIGHTS RESERVED

", + "language": null + }, + { + "key": "dc.description", + "value": "

Another introductory text dolor sit amet, consectetur adipiscing elit. Duis laoreet lorem erat, eget auctor est ultrices quis. Nullam ac tincidunt quam. In nec nisl odio. In egestas aliquam tincidunt.

\r\n

Integer vitae diam id dolor pharetra dignissim in sed enim. Vivamus pulvinar tristique sem a iaculis. Aenean ultricies dui vel facilisis laoreet. Integer porta erat eu ultrices rhoncus. Sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum.

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "Another collection for testing purposes", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

Some more news sed condimentum malesuada ex sit amet ullamcorper. Morbi a ipsum dolor. Vivamus interdum eget lacus ut fermentum. Donec sed ultricies erat, nec sollicitudin mauris. Duis varius nulla quis quam vulputate, at hendrerit turpis rutrum. Integer nec facilisis sapien. Fusce fringilla malesuada lectus id pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae

", + "language": null + } + ] } ] } From 8c16918728b3a0f572057b3a4dcf5de218753a9d Mon Sep 17 00:00:00 2001 From: Christian Scheible Date: Fri, 16 Jun 2017 12:34:17 +0200 Subject: [PATCH 11/12] Added unsubscribe to community logo subscription. --- .../collection-page.component.html | 4 +- .../community-page.component.html | 2 +- .../community-page.component.ts | 18 +- src/backend/communities.ts | 168 +++++++++--------- 4 files changed, 100 insertions(+), 92 deletions(-) diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index f8bfdbc5de..64520d3e84 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -22,11 +22,11 @@ > + [hasInnerHtml]="true"> > + [title]="'collection.page.license'">
diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index 83f6a54033..8a1fbdf18c 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -16,7 +16,7 @@ [content]="(communityData.payload | async)?.sidebarText" [hasInnerHtml]="true" [title]="'community.page.news'"> - + ; logoData: RemoteData; + private subs: Subscription[] = []; constructor( private communityDataService: CommunityDataService, @@ -24,12 +26,16 @@ export class CommunityPageComponent implements OnInit { ngOnInit(): void { this.route.params.subscribe((params: Params) => { - this.communityData = this.communityDataService.findById(params['id']) - this.communityData.payload - .subscribe(community => this.logoData = community.logo); + this.communityData = this.communityDataService.findById(params['id']); + this.subs.push(this.communityData.payload + .subscribe(community => this.logoData = community.logo)); }); } + ngOnDestroy(): void { + this.subs.forEach(sub => sub.unsubscribe()); + } + universalInit() { } -} +} \ No newline at end of file diff --git a/src/backend/communities.ts b/src/backend/communities.ts index 02f474f66b..d301936cdf 100644 --- a/src/backend/communities.ts +++ b/src/backend/communities.ts @@ -1,87 +1,89 @@ -export const COMMUNITIES = [ - { - "name": "Community 1", - "handle": "10673/1", - "id": "6631", - "uuid": "83cd3281-f241-48be-9234-d876f8010d14", - "type": "community", - "metadata": [ - { - "key": "dc.description", - "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "This is a sample top-level community", - "language": null - }, - { - "key": "dc.description.tableofcontents", - "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", - "language": null - }, - { - "key": "dc.rights", - "value": "

If this Community had special copyright text to display, it would be displayed here.

", - "language": null - }, - { - "key": "dc.title", - "value": "Sample Community", - "language": null - } - ], - "_links": { - "self": { - "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" - }, - "collections": [ - { "href": "/collections/5179" } +export const COMMUNITIES = { + "communities": [ + { + "name": "Community 1", + "handle": "10673/1", + "id": "6631", + "uuid": "83cd3281-f241-48be-9234-d876f8010d14", + "type": "community", + "metadata": [ + { + "key": "dc.description", + "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "This is a sample top-level community", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", + "language": null + }, + { + "key": "dc.rights", + "value": "

If this Community had special copyright text to display, it would be displayed here.

", + "language": null + }, + { + "key": "dc.title", + "value": "Sample Community", + "language": null + } ], + "_links": { + "self": { + "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" + }, + "collections": [ + { "href": "/collections/5179" } + ], "logo": { "href": "/bitstreams/4688" } - } - }, - { - "name": "Community 2", - "handle": "10673/2", - "id": "2365", - "uuid": "80eec4c6-70bd-4beb-b3d4-5d46c6343157", - "type": "community", - "metadata": [ - { - "key": "dc.description", - "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", - "language": null - }, - { - "key": "dc.description.abstract", - "value": "This is a sample top-level community", - "language": null - }, - { - "key": "dc.description.tableofcontents", - "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", - "language": null - }, - { - "key": "dc.rights", - "value": "

If this Community had special copyright text to display, it would be displayed here.

", - "language": null - }, - { - "key": "dc.title", - "value": "Sample Community", - "language": null } - ], - "_links": { - "self": { - "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" - }, - "collections": [ - { "href": "/collections/6547" } - ] + }, + { + "name": "Community 2", + "handle": "10673/2", + "id": "2365", + "uuid": "80eec4c6-70bd-4beb-b3d4-5d46c6343157", + "type": "community", + "metadata": [ + { + "key": "dc.description", + "value": "

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

", + "language": null + }, + { + "key": "dc.description.abstract", + "value": "This is a sample top-level community", + "language": null + }, + { + "key": "dc.description.tableofcontents", + "value": "

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

", + "language": null + }, + { + "key": "dc.rights", + "value": "

If this Community had special copyright text to display, it would be displayed here.

", + "language": null + }, + { + "key": "dc.title", + "value": "Sample Community", + "language": null + } + ], + "_links": { + "self": { + "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" + }, + "collections": [ + { "href": "/collections/6547" } + ] + } } - } -]; + ] +}; \ No newline at end of file From f6550e2628a0462c78b7076e3db5d988994d4b05 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 19 Jun 2017 15:20:48 +0200 Subject: [PATCH 12/12] fixed issue where resources that were fetched from a list where not able to be rendered separately --- .../builders/remote-data-build.service.ts | 55 +++++++++---------- src/app/core/cache/object-cache.actions.ts | 9 ++- .../core/cache/object-cache.reducer.spec.ts | 15 +++-- src/app/core/cache/object-cache.reducer.ts | 4 +- src/app/core/cache/object-cache.service.ts | 29 ++++++++-- src/app/core/data/request.effects.ts | 22 ++++---- src/app/core/data/request.service.ts | 17 +++++- src/backend/communities.ts | 6 +- 8 files changed, 100 insertions(+), 57 deletions(-) diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 2096d47459..00e99940e1 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -30,37 +30,33 @@ export class RemoteDataBuildService { href: string, normalizedType: GenericConstructor ): RemoteData { - const requestObs = this.store.select('core', 'data', 'request', href); - const responseCacheObs = this.responseCache.get(href); + const requestHrefObs = this.objectCache.getRequestHrefBySelfLink(href); - const requestPending = requestObs.map((entry: RequestEntry) => hasValue(entry) && entry.requestPending).distinctUntilChanged(); + const requestObs = Observable.race( + this.store.select('core', 'data', 'request', href).filter(entry => hasValue(entry)), + requestHrefObs.flatMap(requestHref => + this.store.select('core', 'data', 'request', requestHref)).filter(entry => hasValue(entry)) + ); - const responsePending = requestObs.map((entry: RequestEntry) => hasValue(entry) && entry.responsePending).distinctUntilChanged(); + const responseCacheObs = Observable.race( + this.responseCache.get(href).filter(entry => hasValue(entry)), + requestHrefObs.flatMap(requestHref => this.responseCache.get(requestHref)).filter(entry => hasValue(entry)) + ); + + const requestPending = requestObs.map((entry: RequestEntry) => entry.requestPending).distinctUntilChanged(); + + const responsePending = requestObs.map((entry: RequestEntry) => entry.responsePending).distinctUntilChanged(); const isSuccessFul = responseCacheObs - .map((entry: ResponseCacheEntry) => hasValue(entry) && entry.response.isSuccessful).distinctUntilChanged(); + .map((entry: ResponseCacheEntry) => entry.response.isSuccessful).distinctUntilChanged(); const errorMessage = responseCacheObs - .filter((entry: ResponseCacheEntry) => hasValue(entry) && !entry.response.isSuccessful) + .filter((entry: ResponseCacheEntry) => !entry.response.isSuccessful) .map((entry: ResponseCacheEntry) => ( entry.response).errorMessage) .distinctUntilChanged(); - const payload = - Observable.race( - this.objectCache.getBySelfLink(href, normalizedType), - responseCacheObs - .filter((entry: ResponseCacheEntry) => hasValue(entry) && entry.response.isSuccessful) - .map((entry: ResponseCacheEntry) => ( entry.response).resourceUUIDs) - .flatMap((resourceUUIDs: Array) => { - if (isNotEmpty(resourceUUIDs)) { - return this.objectCache.get(resourceUUIDs[0], normalizedType); - } - else { - return Observable.of(undefined); - } - }) - .distinctUntilChanged() - ).map((normalized: TNormalized) => { + const payload = this.objectCache.getBySelfLink(href, normalizedType) + .map((normalized: TNormalized) => { return this.build(normalized); }); @@ -78,23 +74,24 @@ export class RemoteDataBuildService { href: string, normalizedType: GenericConstructor ): RemoteData { - const requestObs = this.store.select('core', 'data', 'request', href); - const responseCacheObs = this.responseCache.get(href); + const requestObs = this.store.select('core', 'data', 'request', href) + .filter(entry => hasValue(entry)); + const responseCacheObs = this.responseCache.get(href).filter(entry => hasValue(entry)); - const requestPending = requestObs.map((entry: RequestEntry) => hasValue(entry) && entry.requestPending).distinctUntilChanged(); + const requestPending = requestObs.map((entry: RequestEntry) => entry.requestPending).distinctUntilChanged(); - const responsePending = requestObs.map((entry: RequestEntry) => hasValue(entry) && entry.responsePending).distinctUntilChanged(); + const responsePending = requestObs.map((entry: RequestEntry) => entry.responsePending).distinctUntilChanged(); const isSuccessFul = responseCacheObs - .map((entry: ResponseCacheEntry) => hasValue(entry) && entry.response.isSuccessful).distinctUntilChanged(); + .map((entry: ResponseCacheEntry) => entry.response.isSuccessful).distinctUntilChanged(); const errorMessage = responseCacheObs - .filter((entry: ResponseCacheEntry) => hasValue(entry) && !entry.response.isSuccessful) + .filter((entry: ResponseCacheEntry) => !entry.response.isSuccessful) .map((entry: ResponseCacheEntry) => ( entry.response).errorMessage) .distinctUntilChanged(); const payload = responseCacheObs - .filter((entry: ResponseCacheEntry) => hasValue(entry) && entry.response.isSuccessful) + .filter((entry: ResponseCacheEntry) => entry.response.isSuccessful) .map((entry: ResponseCacheEntry) => ( entry.response).resourceUUIDs) .flatMap((resourceUUIDs: Array) => { return this.objectCache.getList(resourceUUIDs, normalizedType) diff --git a/src/app/core/cache/object-cache.actions.ts b/src/app/core/cache/object-cache.actions.ts index cc9e557de4..9d34c01219 100644 --- a/src/app/core/cache/object-cache.actions.ts +++ b/src/app/core/cache/object-cache.actions.ts @@ -20,6 +20,7 @@ export class AddToObjectCacheAction implements Action { objectToCache: CacheableObject; timeAdded: number; msToLive: number; + requestHref: string; }; /** @@ -31,9 +32,13 @@ export class AddToObjectCacheAction implements Action { * the time it was added * @param msToLive * the amount of milliseconds before it should expire + * @param requestHref + * The href of the request that resulted in this object + * This isn't necessarily the same as the object's self + * link, it could have been part of a list for example */ - constructor(objectToCache: CacheableObject, timeAdded: number, msToLive: number) { - this.payload = { objectToCache, timeAdded, msToLive }; + constructor(objectToCache: CacheableObject, timeAdded: number, msToLive: number, requestHref: string) { + this.payload = { objectToCache, timeAdded, msToLive, requestHref }; } } diff --git a/src/app/core/cache/object-cache.reducer.spec.ts b/src/app/core/cache/object-cache.reducer.spec.ts index 4d8e116e4f..3331be569e 100644 --- a/src/app/core/cache/object-cache.reducer.spec.ts +++ b/src/app/core/cache/object-cache.reducer.spec.ts @@ -24,7 +24,8 @@ describe("objectCacheReducer", () => { foo: "bar" }, timeAdded: new Date().getTime(), - msToLive: 900000 + msToLive: 900000, + requestHref: "https://rest.api/endpoint/uuid1" }, [uuid2]: { data: { @@ -32,7 +33,8 @@ describe("objectCacheReducer", () => { foo: "baz" }, timeAdded: new Date().getTime(), - msToLive: 900000 + msToLive: 900000, + requestHref: "https://rest.api/endpoint/uuid2" } }; deepFreeze(testState); @@ -56,7 +58,8 @@ describe("objectCacheReducer", () => { const objectToCache = {uuid: uuid1}; const timeAdded = new Date().getTime(); const msToLive = 900000; - const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive); + const requestHref = "https://rest.api/endpoint/uuid1"; + const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive, requestHref); const newState = objectCacheReducer(state, action); expect(newState[uuid1].data).toEqual(objectToCache); @@ -68,7 +71,8 @@ describe("objectCacheReducer", () => { const objectToCache = {uuid: uuid1, foo: "baz", somethingElse: true}; const timeAdded = new Date().getTime(); const msToLive = 900000; - const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive); + const requestHref = "https://rest.api/endpoint/uuid1"; + const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive, requestHref); const newState = objectCacheReducer(testState, action); expect(newState[uuid1].data['foo']).toBe("baz"); @@ -80,7 +84,8 @@ describe("objectCacheReducer", () => { const objectToCache = {uuid: uuid1}; const timeAdded = new Date().getTime(); const msToLive = 900000; - const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive); + const requestHref = "https://rest.api/endpoint/uuid1"; + const action = new AddToObjectCacheAction(objectToCache, timeAdded, msToLive, requestHref); deepFreeze(state); objectCacheReducer(state, action); diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index 85e1fdc2b3..113a06cd06 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -22,6 +22,7 @@ export class ObjectCacheEntry implements CacheEntry { data: CacheableObject; timeAdded: number; msToLive: number; + requestHref: string; } /** @@ -83,7 +84,8 @@ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheActio [action.payload.objectToCache.uuid]: { data: action.payload.objectToCache, timeAdded: action.payload.timeAdded, - msToLive: action.payload.msToLive + msToLive: action.payload.msToLive, + requestHref: action.payload.requestHref } }); } diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index ec0bea4a97..63bfd44c82 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -22,9 +22,13 @@ export class ObjectCacheService { * The object to add * @param msToLive * The number of milliseconds it should be cached for + * @param requestHref + * The href of the request that resulted in this object + * This isn't necessarily the same as the object's self + * link, it could have been part of a list for example */ - add(objectToCache: CacheableObject, msToLive: number): void { - this.store.dispatch(new AddToObjectCacheAction(objectToCache, new Date().getTime(), msToLive)); + add(objectToCache: CacheableObject, msToLive: number, requestHref: string): void { + this.store.dispatch(new AddToObjectCacheAction(objectToCache, new Date().getTime(), msToLive, requestHref)); } /** @@ -54,9 +58,7 @@ export class ObjectCacheService { * An observable of the requested object */ get(uuid: string, type: GenericConstructor): Observable { - return this.store.select('core', 'cache', 'object', uuid) - .filter(entry => this.isValid(entry)) - .distinctUntilChanged() + return this.getEntry(uuid) .map((entry: ObjectCacheEntry) => Object.assign(new type(), entry.data)); } @@ -65,6 +67,23 @@ export class ObjectCacheService { .flatMap((uuid: string) => this.get(uuid, type)) } + private getEntry(uuid: string): Observable { + return this.store.select('core', 'cache', 'object', uuid) + .filter(entry => this.isValid(entry)) + .distinctUntilChanged(); + } + + getRequestHref(uuid: string): Observable { + return this.getEntry(uuid) + .map((entry: ObjectCacheEntry) => entry.requestHref) + .distinctUntilChanged(); + } + + getRequestHrefBySelfLink(self: string): Observable { + return this.store.select('core', 'index', 'href', self) + .flatMap((uuid: string) => this.getRequestHref(uuid)); + } + /** * Get an observable for an array of objects of the same type * with the specified UUIDs diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index 64e7aec1fd..f010f2e59c 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -45,7 +45,7 @@ export class RequestEffects { }) .flatMap((entry: RequestEntry) => { return this.restApi.get(entry.request.href) - .map((data: DSpaceRESTV2Response) => this.processEmbedded(data._embedded)) + .map((data: DSpaceRESTV2Response) => this.processEmbedded(data._embedded, entry.request.href)) .map((ids: Array) => new SuccessResponse(ids)) .do((response: Response) => this.responseCache.add(entry.request.href, response, this.EnvConfig.cache.msToLive)) .map((response: Response) => new RequestCompleteAction(entry.request.href)) @@ -54,25 +54,25 @@ export class RequestEffects { .map((response: Response) => new RequestCompleteAction(entry.request.href))); }); - protected processEmbedded(_embedded: any): Array { + protected processEmbedded(_embedded: any, requestHref): Array { if (isNotEmpty(_embedded)) { if (isObjectLevel(_embedded)) { - return this.deserializeAndCache(_embedded); + return this.deserializeAndCache(_embedded, requestHref); } else { let uuids = []; Object.keys(_embedded) .filter(property => _embedded.hasOwnProperty(property)) .forEach(property => { - uuids = [...uuids, ...this.deserializeAndCache(_embedded[property])]; + uuids = [...uuids, ...this.deserializeAndCache(_embedded[property], requestHref)]; }); return uuids; } } } - protected deserializeAndCache(obj): Array { + protected deserializeAndCache(obj, requestHref): Array { let type: ResourceType; const isArray = Array.isArray(obj); @@ -96,19 +96,19 @@ export class RequestEffects { if (isArray) { obj.forEach(o => { if (isNotEmpty(o._embedded)) { - this.processEmbedded(o._embedded); + this.processEmbedded(o._embedded, requestHref); } }); const normalizedObjArr = serializer.deserializeArray(obj); - normalizedObjArr.forEach(t => this.addToObjectCache(t)); + normalizedObjArr.forEach(t => this.addToObjectCache(t, requestHref)); return normalizedObjArr.map(t => t.uuid); } else { if (isNotEmpty(obj._embedded)) { - this.processEmbedded(obj._embedded); + this.processEmbedded(obj._embedded, requestHref); } const normalizedObj = serializer.deserialize(obj); - this.addToObjectCache(normalizedObj); + this.addToObjectCache(normalizedObj, requestHref); return [normalizedObj.uuid]; } @@ -125,10 +125,10 @@ export class RequestEffects { } } - protected addToObjectCache(co: CacheableObject): void { + protected addToObjectCache(co: CacheableObject, requestHref: string): void { if (hasNoValue(co) || hasNoValue(co.uuid)) { throw new Error('The server returned an invalid object'); } - this.objectCache.add(co, this.EnvConfig.cache.msToLive); + this.objectCache.add(co, this.EnvConfig.cache.msToLive, requestHref); } } diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index 35ce8ea078..47e4574955 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -8,6 +8,9 @@ import { RequestConfigureAction, RequestExecuteAction } from "./request.actions" import { ResponseCacheService } from "../cache/response-cache.service"; import { ObjectCacheService } from "../cache/object-cache.service"; import { CacheableObject } from "../cache/object-cache.reducer"; +import { ResponseCacheEntry } from "../cache/response-cache.reducer"; +import { request } from "http"; +import { SuccessResponse } from "../cache/response-cache.models"; @Injectable() export class RequestService { @@ -35,7 +38,19 @@ export class RequestService { } configure(request: Request): void { - const isCached = this.objectCache.hasBySelfLink(request.href); + let isCached = this.objectCache.hasBySelfLink(request.href); + + if (!isCached && this.responseCache.has(request.href)) { + //if it isn't cached it may be a list endpoint, if so verify + //every object included in the response is still cached + this.responseCache.get(request.href) + .take(1) + .filter((entry: ResponseCacheEntry) => entry.response.isSuccessful) + .map((entry: ResponseCacheEntry) => ( entry.response).resourceUUIDs) + .map((resourceUUIDs: Array) => resourceUUIDs.every(uuid => this.objectCache.has(uuid))) + .subscribe(c => isCached = c); + } + const isPending = this.isPending(request.href); if (!(isCached || isPending)) { diff --git a/src/backend/communities.ts b/src/backend/communities.ts index d301936cdf..35a86aeaf9 100644 --- a/src/backend/communities.ts +++ b/src/backend/communities.ts @@ -35,7 +35,7 @@ export const COMMUNITIES = { ], "_links": { "self": { - "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" + "href": "/communities/6631" }, "collections": [ { "href": "/collections/5179" } @@ -78,7 +78,7 @@ export const COMMUNITIES = { ], "_links": { "self": { - "href": "http://dspace7.4science.it/dspace-spring-rest/api/core/community/9076bd16-e69a-48d6-9e41-0238cb40d863" + "href": "/communities/2365" }, "collections": [ { "href": "/collections/6547" } @@ -86,4 +86,4 @@ export const COMMUNITIES = { } } ] -}; \ No newline at end of file +};