diff --git a/.travis.yml b/.travis.yml
index e009520b68..119151e71d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,14 +18,16 @@ cache:
directories:
- node_modules
+bundler_args: --retry 5
+
before_install:
- - yarn run global
+ - travis_retry yarn run global
install:
- - yarn install
+ - travis_retry yarn install
before_script:
- - yarn run build
+ - travis_wait yarn run build
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
diff --git a/resources/i18n/en.json b/resources/i18n/en.json
index 95358dc446..7489228eb5 100644
--- a/resources/i18n/en.json
+++ b/resources/i18n/en.json
@@ -4,7 +4,12 @@
"link.dspace": "DSpace software",
"link.duraspace": "DuraSpace"
},
-
+ "collection": {
+ "page": {
+ "news": "News",
+ "license": "License"
+ }
+ },
"item": {
"page": {
"author": "Author",
@@ -12,24 +17,31 @@
"date": "Date",
"uri": "URI",
"files": "Files",
- "collections": "Collections"
+ "collections": "Collections",
+ "filesection": {
+ "download": "Download",
+ "name": "Name:",
+ "format": "Format:",
+ "size": "Size:",
+ "description": "Description:"
+ },
+ "link": {
+ "simple": "Simple item page",
+ "full": "Full item page"
+ }
}
},
-
"nav": {
"home": "Home"
},
-
"pagination": {
"results-per-page": "Results Per Page",
"showing": {
- "label" : "Now showing items ",
+ "label": "Now showing items ",
"detail": "{{ range }} of {{ total }}"
}
},
-
"title": "DSpace",
-
"404": {
"help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ",
"page-not-found": "page not found",
@@ -37,7 +49,6 @@
"home-page": "Take me to the home page"
}
},
-
"home": {
"top-level-communities": {
"head": "Communities in DSpace",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 42304c865e..95bfc73517 100755
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -9,6 +9,7 @@ import { SharedModule } from './shared/shared.module';
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 { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
@@ -22,6 +23,7 @@ import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
SharedModule,
HomeModule,
ItemPageModule,
+ CollectionPageModule,
CoreModule.forRoot(),
AppRoutingModule
],
diff --git a/src/app/collection-page/collection-page-routing.module.ts b/src/app/collection-page/collection-page-routing.module.ts
new file mode 100644
index 0000000000..ac8c9b9cb5
--- /dev/null
+++ b/src/app/collection-page/collection-page-routing.module.ts
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { CollectionPageComponent } from './collection-page.component';
+
+@NgModule({
+ imports: [
+ RouterModule.forChild([
+ { path: 'collections/:id', component: CollectionPageComponent }
+ ])
+ ]
+})
+export class CollectionPageRoutingModule { }
diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html
new file mode 100644
index 0000000000..e9a4ab9916
--- /dev/null
+++ b/src/app/collection-page/collection-page.component.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/item-page/item-page.component.scss b/src/app/collection-page/collection-page.component.scss
similarity index 100%
rename from src/app/item-page/item-page.component.scss
rename to src/app/collection-page/collection-page.component.scss
diff --git a/src/app/collection-page/collection-page.component.ts b/src/app/collection-page/collection-page.component.ts
new file mode 100644
index 0000000000..42afe78881
--- /dev/null
+++ b/src/app/collection-page/collection-page.component.ts
@@ -0,0 +1,35 @@
+import { Component, 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";
+
+@Component({
+ selector: 'ds-collection-page',
+ styleUrls: ['./collection-page.component.css'],
+ templateUrl: './collection-page.component.html',
+})
+export class CollectionPageComponent implements OnInit {
+ collectionData: RemoteData;
+ logoData: RemoteData;
+
+ constructor(
+ private collectionDataService: CollectionDataService,
+ private route: ActivatedRoute
+ ) {
+ this.universalInit();
+ }
+
+ ngOnInit(): void {
+ this.route.params.subscribe((params: Params) => {
+ this.collectionData = this.collectionDataService.findById(params['id'])
+ this.collectionData.payload
+ .subscribe(collection => this.logoData = collection.logo);
+ });
+ }
+
+ universalInit() {
+ }
+}
diff --git a/src/app/collection-page/collection-page.module.ts b/src/app/collection-page/collection-page.module.ts
new file mode 100644
index 0000000000..9b204cb0bb
--- /dev/null
+++ b/src/app/collection-page/collection-page.module.ts
@@ -0,0 +1,33 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { TranslateModule } from "@ngx-translate/core";
+
+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({
+ imports: [
+ CollectionPageRoutingModule,
+ CommonModule,
+ TranslateModule,
+ ],
+ 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
new file mode 100644
index 0000000000..db7b77d614
--- /dev/null
+++ b/src/app/collection-page/copyright/collection-page-copyright.component.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/src/app/collection-page/copyright/collection-page-copyright.component.scss b/src/app/collection-page/copyright/collection-page-copyright.component.scss
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-page/copyright/collection-page-copyright.component.scss
@@ -0,0 +1 @@
+@import '../../../styles/variables.scss';
\ 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
new file mode 100644
index 0000000000..e4bc21553f
--- /dev/null
+++ b/src/app/collection-page/copyright/collection-page-copyright.component.ts
@@ -0,0 +1,11 @@
+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/field-wrapper/field-wrapper.component.html b/src/app/collection-page/field-wrapper/field-wrapper.component.html
new file mode 100644
index 0000000000..677ff2f918
--- /dev/null
+++ b/src/app/collection-page/field-wrapper/field-wrapper.component.html
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/src/app/collection-page/field-wrapper/field-wrapper.component.scss b/src/app/collection-page/field-wrapper/field-wrapper.component.scss
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-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/collection-page/field-wrapper/field-wrapper.component.ts b/src/app/collection-page/field-wrapper/field-wrapper.component.ts
new file mode 100644
index 0000000000..c8420661ea
--- /dev/null
+++ b/src/app/collection-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/collection-page/introductory-text/collection-page-introductory-text.component.html b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.html
new file mode 100644
index 0000000000..904a6d7f21
--- /dev/null
+++ b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.html
@@ -0,0 +1,3 @@
+
+
+
\ 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
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.scss
@@ -0,0 +1 @@
+@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
new file mode 100644
index 0000000000..f6526c9943
--- /dev/null
+++ b/src/app/collection-page/introductory-text/collection-page-introductory-text.component.ts
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 0000000000..af0a6e4261
--- /dev/null
+++ b/src/app/collection-page/license/collection-page-license.component.html
@@ -0,0 +1,4 @@
+
+ {{ '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
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-page/license/collection-page-license.component.scss
@@ -0,0 +1 @@
+@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
new file mode 100644
index 0000000000..8f269cca8c
--- /dev/null
+++ b/src/app/collection-page/license/collection-page-license.component.ts
@@ -0,0 +1,11 @@
+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/logo/collection-page-logo.component.html b/src/app/collection-page/logo/collection-page-logo.component.html
new file mode 100644
index 0000000000..1c331e2e25
--- /dev/null
+++ b/src/app/collection-page/logo/collection-page-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/collection-page/logo/collection-page-logo.component.scss
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-page/logo/collection-page-logo.component.scss
@@ -0,0 +1 @@
+@import '../../../styles/variables.scss';
\ 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
new file mode 100644
index 0000000000..22c34422ea
--- /dev/null
+++ b/src/app/collection-page/logo/collection-page-logo.component.ts
@@ -0,0 +1,13 @@
+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.html b/src/app/collection-page/name/collection-page-name.component.html
new file mode 100644
index 0000000000..21f1f65331
--- /dev/null
+++ b/src/app/collection-page/name/collection-page-name.component.html
@@ -0,0 +1 @@
+{{ name }}
\ No newline at end of file
diff --git a/src/app/collection-page/name/collection-page-name.component.scss b/src/app/collection-page/name/collection-page-name.component.scss
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-page/name/collection-page-name.component.scss
@@ -0,0 +1 @@
+@import '../../../styles/variables.scss';
\ No newline at end of file
diff --git a/src/app/collection-page/name/collection-page-name.component.ts b/src/app/collection-page/name/collection-page-name.component.ts
new file mode 100644
index 0000000000..30121fd01b
--- /dev/null
+++ b/src/app/collection-page/name/collection-page-name.component.ts
@@ -0,0 +1,11 @@
+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/collection-page/news/collection-page-news.component.html b/src/app/collection-page/news/collection-page-news.component.html
new file mode 100644
index 0000000000..bd17c7ea77
--- /dev/null
+++ b/src/app/collection-page/news/collection-page-news.component.html
@@ -0,0 +1,4 @@
+
+ {{ '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
new file mode 100644
index 0000000000..ad84b72f8c
--- /dev/null
+++ b/src/app/collection-page/news/collection-page-news.component.scss
@@ -0,0 +1 @@
+@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
new file mode 100644
index 0000000000..479c37a7c6
--- /dev/null
+++ b/src/app/collection-page/news/collection-page-news.component.ts
@@ -0,0 +1,11 @@
+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/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts
index af47b62fe0..2096d47459 100644
--- a/src/app/core/cache/builders/remote-data-build.service.ts
+++ b/src/app/core/cache/builders/remote-data-build.service.ts
@@ -135,9 +135,12 @@ export class RemoteDataBuildService {
});
}, 0);
- links[relationship] = normalized[relationship].map((href: string) => {
- return this.buildSingle(href, resourceConstructor);
+ let rdArr = [];
+ normalized[relationship].forEach((href: string) => {
+ rdArr.push(this.buildSingle(href, resourceConstructor));
});
+
+ links[relationship] = this.aggregate(rdArr);
}
else {
// without the setTimeout, the actions inside requestService.configure
@@ -154,4 +157,49 @@ export class RemoteDataBuildService {
const domainModel = getMapsTo(normalized.constructor);
return Object.assign(new domainModel(), normalized, links);
}
+
+ aggregate(input: RemoteData[]): RemoteData {
+ const requestPending = Observable.combineLatest(
+ ...input.map(rd => rd.isRequestPending),
+ ).map((...pendingArray) => pendingArray.every(e => e === true))
+ .distinctUntilChanged();
+
+ const responsePending = Observable.combineLatest(
+ ...input.map(rd => rd.isResponsePending),
+ ).map((...pendingArray) => pendingArray.every(e => e === true))
+ .distinctUntilChanged();
+
+ const isSuccessFul = Observable.combineLatest(
+ ...input.map(rd => rd.hasSucceeded),
+ ).map((...successArray) => successArray.every(e => e === true))
+ .distinctUntilChanged();
+
+ const errorMessage = Observable.combineLatest(
+ ...input.map(rd => rd.errorMessage),
+ ).map((...errors) => errors
+ .map((e, idx) => {
+ if (hasValue(e)) {
+ return `[${idx}]: ${e}`;
+ }
+ })
+ .filter(e => hasValue(e))
+ .join(", ")
+ );
+
+ const payload = > Observable.combineLatest(
+ ...input.map(rd => rd.payload)
+ );
+
+ return new RemoteData(
+ // This is an aggregated object, it doesn't necessarily correspond
+ // to a single REST endpoint, so instead of a self link, use the
+ // current time in ms for a somewhat unique id
+ `${new Date().getTime()}`,
+ requestPending,
+ responsePending,
+ isSuccessFul,
+ errorMessage,
+ payload
+ );
+ }
}
diff --git a/src/app/core/cache/models/normalized-bitstream.model.ts b/src/app/core/cache/models/normalized-bitstream.model.ts
index 57b4f63346..c89cf5dc05 100644
--- a/src/app/core/cache/models/normalized-bitstream.model.ts
+++ b/src/app/core/cache/models/normalized-bitstream.model.ts
@@ -16,13 +16,20 @@ export class NormalizedBitstream extends NormalizedDSpaceObject {
/**
* The relative path to this Bitstream's file
*/
+ @autoserialize
url: string;
/**
* The mime type of this Bitstream
*/
+ @autoserialize
mimetype: string;
+ /**
+ * The format of this Bitstream
+ */
+ format: string;
+
/**
* The description of this Bitstream
*/
diff --git a/src/app/core/cache/models/normalized-collection.model.ts b/src/app/core/cache/models/normalized-collection.model.ts
index e0f96ff805..86a1ba177a 100644
--- a/src/app/core/cache/models/normalized-collection.model.ts
+++ b/src/app/core/cache/models/normalized-collection.model.ts
@@ -17,6 +17,8 @@ export class NormalizedCollection extends NormalizedDSpaceObject {
/**
* The Bitstream that represents the logo of this Collection
*/
+ @autoserialize
+ @relationship(NormalizedDSOType.NormalizedBitstream)
logo: string;
/**
diff --git a/src/app/core/shared/bitstream.model.ts b/src/app/core/shared/bitstream.model.ts
index 5325e395d8..06bdf41f30 100644
--- a/src/app/core/shared/bitstream.model.ts
+++ b/src/app/core/shared/bitstream.model.ts
@@ -27,7 +27,7 @@ export class Bitstream extends DSpaceObject {
/**
* An array of Bundles that are direct parents of this Bitstream
*/
- parents: Array>;
+ parents: RemoteData;
/**
* The Bundle that owns this Bitstream
diff --git a/src/app/core/shared/bundle.model.ts b/src/app/core/shared/bundle.model.ts
index 7c2f6b05d4..8f3a284fb6 100644
--- a/src/app/core/shared/bundle.model.ts
+++ b/src/app/core/shared/bundle.model.ts
@@ -12,13 +12,13 @@ export class Bundle extends DSpaceObject {
/**
* An array of Items that are direct parents of this Bundle
*/
- parents: Array>;
+ parents: RemoteData- ;
/**
* The Item that owns this Bundle
*/
owner: Item;
- bitstreams: Array>
+ bitstreams: RemoteData
}
diff --git a/src/app/core/shared/collection.model.ts b/src/app/core/shared/collection.model.ts
index 4287eff63c..30814726b8 100644
--- a/src/app/core/shared/collection.model.ts
+++ b/src/app/core/shared/collection.model.ts
@@ -58,13 +58,13 @@ export class Collection extends DSpaceObject {
/**
* An array of Collections that are direct parents of this Collection
*/
- parents: Array>;
+ parents: RemoteData;
/**
* The Collection that owns this Collection
*/
owner: Collection;
- items: Array>;
+ items: RemoteData
- ;
}
diff --git a/src/app/core/shared/community.model.ts b/src/app/core/shared/community.model.ts
index 9639abd258..67c8211fd2 100644
--- a/src/app/core/shared/community.model.ts
+++ b/src/app/core/shared/community.model.ts
@@ -50,13 +50,13 @@ export class Community extends DSpaceObject {
/**
* An array of Communities that are direct parents of this Community
*/
- parents: Array>;
+ parents: RemoteData;
/**
* The Community that owns this Community
*/
owner: Community;
- collections: Array>;
+ collections: RemoteData;
}
diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts
index 9609782735..ca7c67207a 100644
--- a/src/app/core/shared/dspace-object.model.ts
+++ b/src/app/core/shared/dspace-object.model.ts
@@ -39,7 +39,7 @@ export abstract class DSpaceObject implements CacheableObject {
/**
* An array of DSpaceObjects that are direct parents of this DSpaceObject
*/
- parents: Array>;
+ parents: RemoteData;
/**
* The DSpaceObject that owns this DSpaceObject
diff --git a/src/app/core/shared/item.model.spec.ts b/src/app/core/shared/item.model.spec.ts
new file mode 100644
index 0000000000..e20bd6e592
--- /dev/null
+++ b/src/app/core/shared/item.model.spec.ts
@@ -0,0 +1,115 @@
+import { TestBed, async } from '@angular/core/testing';
+import { Item } from "./item.model";
+import { Bundle } from "./bundle.model";
+import { Observable } from "rxjs";
+import { RemoteData } from "../data/remote-data";
+import { Bitstream } from "./bitstream.model";
+
+
+describe('Item', () => {
+
+
+ let item: Item;
+ const thumbnailBundleName = "THUMBNAIL";
+ const originalBundleName = "ORIGINAL";
+ const thumbnailPath = "thumbnail.jpg";
+ const bitstream1Path = "document.pdf";
+ const bitstream2Path = "otherfile.doc";
+
+ const nonExistingBundleName = "c1e568f7-d14e-496b-bdd7-07026998cc00";
+ let remoteBundles;
+ let thumbnailBundle;
+ let originalBundle;
+
+ beforeEach(() => {
+ const thumbnail = {
+ retrieve: thumbnailPath
+ };
+
+ const bitstreams = [{
+ retrieve: bitstream1Path
+ }, {
+ retrieve: bitstream2Path
+ }];
+
+ const remoteDataThumbnail = createRemoteDataObject(thumbnail);
+ const remoteDataFiles = createRemoteDataObject(bitstreams);
+
+
+ // Create Bundles
+
+ const bundles =
+ [
+ {
+ name: thumbnailBundleName,
+ primaryBitstream: remoteDataThumbnail
+ },
+
+ {
+ name: originalBundleName,
+ bitstreams: remoteDataFiles
+ }];
+
+ remoteBundles = createRemoteDataObject(bundles);
+
+ item = Object.assign(new Item(), { bundles: remoteBundles });
+
+ });
+
+
+ it('should return the bundle with the given name of this item when the bundle exists', () => {
+ let name: string = thumbnailBundleName;
+ let bundle: Observable = item.getBundle(name);
+ bundle.map(b => expect(b.name).toBe(name));
+ });
+
+ it('should return null when no bundle with this name exists for this item', () => {
+ let name: string = nonExistingBundleName;
+ let bundle: Observable = item.getBundle(name);
+ bundle.map(b => expect(b).toBeUndefined());
+ });
+
+
+ describe("get thumbnail", () => {
+ beforeEach(() => {
+ spyOn(item, 'getBundle').and.returnValue(Observable.of(thumbnailBundle));
+ });
+
+ it('should return the thumbnail (the primaryBitstream in the bundle "THUMBNAIL") of this item', () => {
+ let path: string = thumbnailPath;
+ let bitstream: Observable = item.getThumbnail();
+ bitstream.map(b => expect(b.retrieve).toBe(path));
+ });
+ });
+
+
+ describe("get files", () => {
+ beforeEach(() => {
+ spyOn(item, 'getBundle').and.returnValue(Observable.of(originalBundle));
+ });
+
+ it('should return all files in the ORIGINAL bundle', () => {
+ let paths = [bitstream1Path, bitstream2Path];
+
+ let files: Observable = item.getFiles();
+ let index = 0;
+ files.map(f => expect(f.length).toBe(2));
+ files.subscribe(
+ array => array.forEach(
+ file => {
+ expect(file.retrieve).toBe(paths[index]);
+ index++;
+ }
+ )
+ )
+ });
+
+ });
+
+
+});
+
+function createRemoteDataObject(object: Object) {
+ return new RemoteData("", Observable.of(false), Observable.of(false), Observable.of(true), Observable.of(undefined), Observable.of(object));
+
+}
\ No newline at end of file
diff --git a/src/app/core/shared/item.model.ts b/src/app/core/shared/item.model.ts
index 92a05263a4..a3e098eed9 100644
--- a/src/app/core/shared/item.model.ts
+++ b/src/app/core/shared/item.model.ts
@@ -4,6 +4,7 @@ import { RemoteData } from "../data/remote-data";
import { Bundle } from "./bundle.model";
import { Bitstream } from "./bitstream.model";
import { Observable } from "rxjs";
+import { hasValue } from "../../shared/empty.util";
export class Item extends DSpaceObject {
@@ -30,51 +31,72 @@ export class Item extends DSpaceObject {
/**
* An array of Collections that are direct parents of this Item
*/
- parents: Array>;
+ parents: RemoteData;
/**
* The Collection that owns this Item
*/
owner: Collection;
- bundles: Array>;
+ bundles: RemoteData;
+
+ /**
+ * Retrieves the thumbnail of this item
+ * @returns {Observable} the primaryBitstream of the "THUMBNAIL" bundle
+ */
getThumbnail(): Observable {
const bundle: Observable = this.getBundle("THUMBNAIL");
- return bundle.flatMap(
- bundle => {
- if (bundle != null) {
- return bundle.primaryBitstream.payload;
- }
- else {
- return Observable.of(undefined);
- }
- }
- );
+ return bundle
+ .filter(bundle => hasValue(bundle))
+ .flatMap(bundle => bundle.primaryBitstream.payload)
+ .startWith(undefined);
}
- getFiles(): Observable>> {
- const bundle: Observable = this.getBundle("ORIGINAL");
- return bundle.map(bundle => {
- if (bundle != null) {
- return bundle.bitstreams.map(bitstream => bitstream.payload)
- }
- });
+ /**
+ * Retrieves the thumbnail for the given original of this item
+ * @returns {Observable} the primaryBitstream of the "THUMBNAIL" bundle
+ */
+ getThumbnailForOriginal(original: Bitstream): Observable {
+ const bundle: Observable = this.getBundle("THUMBNAIL");
+ return bundle
+ .filter(bundle => hasValue(bundle))
+ .flatMap(bundle => bundle
+ .bitstreams.payload.map(files => files
+ .find(thumbnail => thumbnail
+ .name.startsWith(original.name)
+ )
+ )
+ )
+ .startWith(undefined);;
}
+ /**
+ * Retrieves all files that should be displayed on the item page of this item
+ * @returns {Observable>>} an array of all Bitstreams in the "ORIGINAL" bundle
+ */
+ getFiles(name: String = "ORIGINAL"): Observable {
+ const bundle: Observable = this.getBundle(name);
+ return bundle
+ .filter(bundle => hasValue(bundle))
+ .flatMap(bundle => bundle.bitstreams.payload)
+ .startWith([]);
+ }
+
+ /**
+ * Retrieves the bundle of this item by its name
+ * @param name The name of the Bundle that should be returned
+ * @returns {Observable} the Bundle that belongs to this item with the given name
+ */
getBundle(name: String): Observable {
- return Observable.combineLatest(
- ...this.bundles.map(b => b.payload),
- (...bundles: Array) => bundles)
+ return this.bundles.payload
+ .filter(bundles => hasValue(bundles))
.map(bundles => {
return bundles.find((bundle: Bundle) => {
return bundle.name === name
});
- });
- }
-
- getCollections(): Array> {
- return this.parents.map(collection => collection.payload.map(parent => parent));
+ })
+ .startWith(undefined);
}
}
diff --git a/src/app/item-page/collections/collections.component.html b/src/app/item-page/collections/collections.component.html
deleted file mode 100644
index bf764ae182..0000000000
--- a/src/app/item-page/collections/collections.component.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
diff --git a/src/app/item-page/field-components/collections/collections.component.html b/src/app/item-page/field-components/collections/collections.component.html
new file mode 100644
index 0000000000..8f184817c2
--- /dev/null
+++ b/src/app/item-page/field-components/collections/collections.component.html
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/app/item-page/collections/collections.component.ts b/src/app/item-page/field-components/collections/collections.component.ts
similarity index 58%
rename from src/app/item-page/collections/collections.component.ts
rename to src/app/item-page/field-components/collections/collections.component.ts
index 742ac247a1..199fb2b773 100644
--- a/src/app/item-page/collections/collections.component.ts
+++ b/src/app/item-page/field-components/collections/collections.component.ts
@@ -1,7 +1,12 @@
import { Component, Input, OnInit } from '@angular/core';
-import { Collection } from "../../core/shared/collection.model";
+import { Collection } from "../../../core/shared/collection.model";
import { Observable } from "rxjs";
-import { Item } from "../../core/shared/item.model";
+import { Item } from "../../../core/shared/item.model";
+
+/**
+ * This component renders the parent collections section of the item
+ * inside a 'ds-metadata-field-wrapper' component.
+ */
@Component({
selector: 'ds-item-page-collections',
@@ -15,7 +20,7 @@ export class CollectionsComponent implements OnInit {
separator: string = "
"
- collections: Array>;
+ collections: Observable;
constructor() {
this.universalInit();
@@ -26,7 +31,7 @@ export class CollectionsComponent implements OnInit {
}
ngOnInit(): void {
- this.collections = this.item.getCollections();
+ this.collections = this.item.parents.payload;
}
diff --git a/src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.html b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.html
similarity index 100%
rename from src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.html
rename to src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.html
diff --git a/src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.scss b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.scss
similarity index 61%
rename from src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.scss
rename to src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.scss
index 749382bc9a..26f0f6fa65 100644
--- a/src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.scss
+++ b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.scss
@@ -1,4 +1,4 @@
-@import '../../../styles/variables.scss';
+@import '../../../../styles/variables.scss';
:host {
.simple-view-element {
margin-bottom: 15px;
diff --git a/src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.ts b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts
similarity index 73%
rename from src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.ts
rename to src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts
index caae4bd5f1..2b40f33b5d 100644
--- a/src/app/item-page/metadata-field-wrapper/metadata-field-wrapper.component.ts
+++ b/src/app/item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component.ts
@@ -1,5 +1,10 @@
import { Component, Input } from '@angular/core';
+/**
+ * This component renders any content inside this wrapper.
+ * The wrapper prints a label before the content (if available)
+ */
+
@Component({
selector: 'ds-metadata-field-wrapper',
styleUrls: ['./metadata-field-wrapper.component.css'],
diff --git a/src/app/item-page/metadata-uri-values/metadata-uri-values.component.html b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.html
similarity index 100%
rename from src/app/item-page/metadata-uri-values/metadata-uri-values.component.html
rename to src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.html
diff --git a/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.scss b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.scss
new file mode 100644
index 0000000000..96ce861942
--- /dev/null
+++ b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.scss
@@ -0,0 +1 @@
+@import '../../../../styles/variables.scss';
diff --git a/src/app/item-page/metadata-uri-values/metadata-uri-values.component.ts b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts
similarity index 56%
rename from src/app/item-page/metadata-uri-values/metadata-uri-values.component.ts
rename to src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts
index fa4a9ebfc5..398e6ed278 100644
--- a/src/app/item-page/metadata-uri-values/metadata-uri-values.component.ts
+++ b/src/app/item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts
@@ -1,6 +1,14 @@
import { Component, Input } from '@angular/core';
import { MetadataValuesComponent } from "../metadata-values/metadata-values.component";
+/**
+ * This component renders the configured 'values' into the ds-metadata-field-wrapper component as a link.
+ * It puts the given 'separator' between each two values
+ * and creates an 'a' tag for each value,
+ * using the 'linktext' as it's value (if it exists)
+ * and using the values as the 'href' attribute (and as value of the tag when no 'linktext' is defined)
+ */
+
@Component({
selector: 'ds-metadata-uri-values',
styleUrls: ['./metadata-uri-values.component.css'],
diff --git a/src/app/item-page/metadata-values/metadata-values.component.html b/src/app/item-page/field-components/metadata-values/metadata-values.component.html
similarity index 100%
rename from src/app/item-page/metadata-values/metadata-values.component.html
rename to src/app/item-page/field-components/metadata-values/metadata-values.component.html
diff --git a/src/app/item-page/field-components/metadata-values/metadata-values.component.scss b/src/app/item-page/field-components/metadata-values/metadata-values.component.scss
new file mode 100644
index 0000000000..96ce861942
--- /dev/null
+++ b/src/app/item-page/field-components/metadata-values/metadata-values.component.scss
@@ -0,0 +1 @@
+@import '../../../../styles/variables.scss';
diff --git a/src/app/item-page/metadata-values/metadata-values.component.ts b/src/app/item-page/field-components/metadata-values/metadata-values.component.ts
similarity index 71%
rename from src/app/item-page/metadata-values/metadata-values.component.ts
rename to src/app/item-page/field-components/metadata-values/metadata-values.component.ts
index 6ac07ad914..26e18adffd 100644
--- a/src/app/item-page/metadata-values/metadata-values.component.ts
+++ b/src/app/item-page/field-components/metadata-values/metadata-values.component.ts
@@ -1,5 +1,10 @@
import { Component, Input } from '@angular/core';
+/**
+ * This component renders the configured 'values' into the ds-metadata-field-wrapper component.
+ * It puts the given 'separator' between each two values.
+ */
+
@Component({
selector: 'ds-metadata-values',
styleUrls: ['./metadata-values.component.css'],
diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.html b/src/app/item-page/full/field-components/file-section/full-file-section.component.html
new file mode 100644
index 0000000000..d7e1712b7f
--- /dev/null
+++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+ - {{"item.page.filesection.name" | translate}}
+ - {{file.name}}
+
+ - {{"item.page.filesection.size" | translate}}
+ - {{(file.size) | dsFileSize }}
+
+
+ - {{"item.page.filesection.format" | translate}}
+ - {{(file.mimetype)}}
+
+
+ - {{"item.page.filesection.description" | translate}}
+ - {{file.findMetadata("dc.description")}}
+
+
+
+
+
diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.scss b/src/app/item-page/full/field-components/file-section/full-file-section.component.scss
new file mode 100644
index 0000000000..4597c711ff
--- /dev/null
+++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.scss
@@ -0,0 +1,7 @@
+@import '../../../../../styles/variables.scss';
+@import '../../../../../../node_modules/bootstrap/scss/_variables.scss';
+@media screen and (min-width: map-get($grid-breakpoints, md)) {
+ dt {
+ text-align: right;
+ }
+}
\ No newline at end of file
diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.ts b/src/app/item-page/full/field-components/file-section/full-file-section.component.ts
new file mode 100644
index 0000000000..3723bc5450
--- /dev/null
+++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.ts
@@ -0,0 +1,52 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { Bitstream } from "../../../../core/shared/bitstream.model";
+import { Item } from "../../../../core/shared/item.model";
+import { Observable } from "rxjs";
+import { FileSectionComponent } from "../../../simple/field-components/file-section/file-section.component";
+import { hasValue } from "../../../../shared/empty.util";
+
+/**
+ * This component renders the file section of the item
+ * inside a 'ds-metadata-field-wrapper' component.
+ */
+
+@Component({
+ selector: 'ds-item-page-full-file-section',
+ styleUrls: ['./full-file-section.component.css'],
+ templateUrl: './full-file-section.component.html'
+})
+export class FullFileSectionComponent extends FileSectionComponent implements OnInit {
+
+ @Input() item: Item;
+
+ label : string;
+
+ files: Observable;
+
+
+ thumbnails: Map> = new Map();
+
+
+ universalInit() {
+ }
+
+ ngOnInit(): void {
+ super.ngOnInit();
+ }
+
+ initialize(): void {
+ const originals = this.item.getFiles("ORIGINAL");
+ const licenses = this.item.getFiles("LICENSE");
+ this.files = Observable.combineLatest(originals, licenses, (originals, licenses) => [...originals, ...licenses]);
+ this.files.subscribe(
+ files =>
+ files.forEach(
+ original => {
+ const thumbnail: Observable = this.item.getThumbnailForOriginal(original);
+ this.thumbnails.set(original.id, thumbnail);
+ }
+ )
+ )
+ }
+
+}
diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html
new file mode 100644
index 0000000000..b0b1f98037
--- /dev/null
+++ b/src/app/item-page/full/full-item-page.component.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+ {{metadatum.key}} |
+ {{metadatum.value}} |
+ {{metadatum.language}} |
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/item-page/full/full-item-page.component.scss b/src/app/item-page/full/full-item-page.component.scss
new file mode 100644
index 0000000000..65b9262338
--- /dev/null
+++ b/src/app/item-page/full/full-item-page.component.scss
@@ -0,0 +1,7 @@
+@import '../../../styles/variables.scss';
+:host {
+ div.simple-view-link {
+ text-align: center;
+ margin: 20px;
+ }
+}
\ No newline at end of file
diff --git a/src/app/item-page/full/full-item-page.component.ts b/src/app/item-page/full/full-item-page.component.ts
new file mode 100644
index 0000000000..b19fd93677
--- /dev/null
+++ b/src/app/item-page/full/full-item-page.component.ts
@@ -0,0 +1,45 @@
+import { Component, OnInit } from '@angular/core';
+import { Observable } from "rxjs";
+import { ItemPageComponent } from "../simple/item-page.component";
+import { Metadatum } from "../../core/shared/metadatum.model";
+import { ItemDataService } from "../../core/data/item-data.service";
+import { ActivatedRoute } from "@angular/router";
+import { RemoteData } from "../../core/data/remote-data";
+import { Item } from "../../core/shared/item.model";
+
+/**
+ * This component renders a simple item page.
+ * The route parameter 'id' is used to request the item it represents.
+ * All fields of the item that should be displayed, are defined in its template.
+ */
+
+@Component({
+ selector: 'ds-full-item-page',
+ styleUrls: ['./full-item-page.component.css'],
+ templateUrl: './full-item-page.component.html',
+})
+export class FullItemPageComponent extends ItemPageComponent implements OnInit {
+
+ item: RemoteData- ;
+
+ metadata: Observable>;
+
+ constructor(route: ActivatedRoute, items: ItemDataService) {
+ super(route, items);
+ }
+
+ universalInit() {
+
+ }
+
+ /*** AoT inheritance fix, will hopefully be resolved in the near future **/
+ ngOnInit(): void {
+ super.ngOnInit();
+ }
+
+ initialize(params) {
+ super.initialize(params);
+ this.metadata = this.item.payload.map(i => i.metadata);
+ }
+
+}
diff --git a/src/app/item-page/item-page-routing.module.ts b/src/app/item-page/item-page-routing.module.ts
index 64c0a607c5..2cd0c200ad 100644
--- a/src/app/item-page/item-page-routing.module.ts
+++ b/src/app/item-page/item-page-routing.module.ts
@@ -1,12 +1,14 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
-import { ItemPageComponent } from './item-page.component';
+import { ItemPageComponent } from './simple/item-page.component';
+import { FullItemPageComponent } from './full/full-item-page.component';
@NgModule({
imports: [
RouterModule.forChild([
{ path: 'items/:id', pathMatch: 'full', component: ItemPageComponent },
+ { path: 'items/:id/full', component: FullItemPageComponent },
])
]
})
diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts
index ab0e2809f6..8b7bae4477 100644
--- a/src/app/item-page/item-page.module.ts
+++ b/src/app/item-page/item-page.module.ts
@@ -1,23 +1,26 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
-import { ItemPageComponent } from './item-page.component';
+import { ItemPageComponent } from './simple/item-page.component';
import { ItemPageRoutingModule } from './item-page-routing.module';
-import { MetadataValuesComponent } from './metadata-values/metadata-values.component';
-import { MetadataUriValuesComponent } from './metadata-uri-values/metadata-uri-values.component';
-import { MetadataFieldWrapperComponent } from './metadata-field-wrapper/metadata-field-wrapper.component';
-import { ItemPageAuthorFieldComponent } from './specific-field/author/item-page-author-field.component';
-import { ItemPageDateFieldComponent } from './specific-field/date/item-page-date-field.component';
-import { ItemPageAbstractFieldComponent } from './specific-field/abstract/item-page-abstract-field.component';
-import { ItemPageUriFieldComponent } from './specific-field/uri/item-page-uri-field.component';
-import { ItemPageTitleFieldComponent } from './specific-field/title/item-page-title-field.component';
-import { ItemPageSpecificFieldComponent } from './specific-field/item-page-specific-field.component';
+import { MetadataValuesComponent } from './field-components/metadata-values/metadata-values.component';
+import { MetadataUriValuesComponent } from './field-components/metadata-uri-values/metadata-uri-values.component';
+import { MetadataFieldWrapperComponent } from './field-components/metadata-field-wrapper/metadata-field-wrapper.component';
+import { ItemPageAuthorFieldComponent } from './simple/field-components/specific-field/author/item-page-author-field.component';
+import { ItemPageDateFieldComponent } from './simple/field-components/specific-field/date/item-page-date-field.component';
+import { ItemPageAbstractFieldComponent } from './simple/field-components/specific-field/abstract/item-page-abstract-field.component';
+import { ItemPageUriFieldComponent } from './simple/field-components/specific-field/uri/item-page-uri-field.component';
+import { ItemPageTitleFieldComponent } from './simple/field-components/specific-field/title/item-page-title-field.component';
+import { ItemPageSpecificFieldComponent } from './simple/field-components/specific-field/item-page-specific-field.component';
import { SharedModule } from './../shared/shared.module';
-import { FileSectionComponent } from "./file-section/file-section.component";
-import { CollectionsComponent } from "./collections/collections.component";
+import { FileSectionComponent } from "./simple/field-components/file-section/file-section.component";
+import { CollectionsComponent } from "./field-components/collections/collections.component";
+import { FullItemPageComponent } from "./full/full-item-page.component";
+import { FullFileSectionComponent } from "./full/field-components/file-section/full-file-section.component";
@NgModule({
declarations: [
ItemPageComponent,
+ FullItemPageComponent,
MetadataValuesComponent,
MetadataUriValuesComponent,
MetadataFieldWrapperComponent,
@@ -28,7 +31,8 @@ import { CollectionsComponent } from "./collections/collections.component";
ItemPageTitleFieldComponent,
ItemPageSpecificFieldComponent,
FileSectionComponent,
- CollectionsComponent
+ CollectionsComponent,
+ FullFileSectionComponent
],
imports: [
ItemPageRoutingModule,
diff --git a/src/app/item-page/metadata-values/metadata-values.component.scss b/src/app/item-page/metadata-values/metadata-values.component.scss
deleted file mode 100644
index 50be6f5ad0..0000000000
--- a/src/app/item-page/metadata-values/metadata-values.component.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import '../../../styles/variables.scss';
diff --git a/src/app/item-page/file-section/file-section.component.html b/src/app/item-page/simple/field-components/file-section/file-section.component.html
similarity index 63%
rename from src/app/item-page/file-section/file-section.component.html
rename to src/app/item-page/simple/field-components/file-section/file-section.component.html
index 0cc15e090e..149a1b2017 100644
--- a/src/app/item-page/file-section/file-section.component.html
+++ b/src/app/item-page/simple/field-components/file-section/file-section.component.html
@@ -1,8 +1,8 @@
diff --git a/src/app/item-page/file-section/file-section.component.ts b/src/app/item-page/simple/field-components/file-section/file-section.component.ts
similarity index 56%
rename from src/app/item-page/file-section/file-section.component.ts
rename to src/app/item-page/simple/field-components/file-section/file-section.component.ts
index 08b01b8ea1..4cd1daf290 100644
--- a/src/app/item-page/file-section/file-section.component.ts
+++ b/src/app/item-page/simple/field-components/file-section/file-section.component.ts
@@ -1,8 +1,13 @@
import { Component, Input, OnInit } from '@angular/core';
-import { Bitstream } from "../../core/shared/bitstream.model";
-import { Item } from "../../core/shared/item.model";
+import { Bitstream } from "../../../../core/shared/bitstream.model";
+import { Item } from "../../../../core/shared/item.model";
import { Observable } from "rxjs";
+/**
+ * This component renders the file section of the item
+ * inside a 'ds-metadata-field-wrapper' component.
+ */
+
@Component({
selector: 'ds-item-page-file-section',
templateUrl: './file-section.component.html'
@@ -13,21 +18,23 @@ export class FileSectionComponent implements OnInit {
label : string = "item.page.files";
- separator: string = "
"
+ separator: string = "
";
- files: Observable>>;
+ files: Observable;
constructor() {
this.universalInit();
-
}
universalInit() {
}
ngOnInit(): void {
+ this.initialize();
+ }
+
+ initialize(): void {
this.files = this.item.getFiles();
}
-
}
diff --git a/src/app/item-page/specific-field/abstract/item-page-abstract-field.component.ts b/src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts
similarity index 80%
rename from src/app/item-page/specific-field/abstract/item-page-abstract-field.component.ts
rename to src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts
index 3e88117654..f0e410d89e 100644
--- a/src/app/item-page/specific-field/abstract/item-page-abstract-field.component.ts
+++ b/src/app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit, Input } from '@angular/core';
-import { Item } from "../../../core/shared/item.model";
+import { Component, Input } from '@angular/core';
+import { Item } from "../../../../../core/shared/item.model";
import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component";
@Component({
diff --git a/src/app/item-page/specific-field/author/item-page-author-field.component.ts b/src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts
similarity index 80%
rename from src/app/item-page/specific-field/author/item-page-author-field.component.ts
rename to src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts
index 2ff76d509a..5b85038e38 100644
--- a/src/app/item-page/specific-field/author/item-page-author-field.component.ts
+++ b/src/app/item-page/simple/field-components/specific-field/author/item-page-author-field.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit, Input } from '@angular/core';
-import { Item } from "../../../core/shared/item.model";
+import { Component, Input } from '@angular/core';
+import { Item } from "../../../../../core/shared/item.model";
import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component";
@Component({
diff --git a/src/app/item-page/specific-field/date/item-page-date-field.component.ts b/src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts
similarity index 79%
rename from src/app/item-page/specific-field/date/item-page-date-field.component.ts
rename to src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts
index 16b6aad1f0..2d7b3f7c41 100644
--- a/src/app/item-page/specific-field/date/item-page-date-field.component.ts
+++ b/src/app/item-page/simple/field-components/specific-field/date/item-page-date-field.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit, Input } from '@angular/core';
-import { Item } from "../../../core/shared/item.model";
+import { Component, Input } from '@angular/core';
+import { Item } from "../../../../../core/shared/item.model";
import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component";
@Component({
diff --git a/src/app/item-page/specific-field/item-page-specific-field.component.html b/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.html
similarity index 100%
rename from src/app/item-page/specific-field/item-page-specific-field.component.html
rename to src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.html
diff --git a/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts b/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts
new file mode 100644
index 0000000000..20c9528ebe
--- /dev/null
+++ b/src/app/item-page/simple/field-components/specific-field/item-page-specific-field.component.ts
@@ -0,0 +1,40 @@
+import { Component, Input } from '@angular/core';
+import { Item } from "../../../../core/shared/item.model";
+
+/**
+ * This component can be used to represent metadata on a simple item page.
+ * It expects one input parameter of type Item to which the metadata belongs.
+ * This class can be extended to print certain metadata.
+ */
+
+@Component({
+ templateUrl: './item-page-specific-field.component.html'
+})
+export class ItemPageSpecificFieldComponent {
+
+ @Input() item: Item;
+
+ /**
+ * Fields (schema.element.qualifier) used to render their values.
+ */
+ fields : string[];
+
+ /**
+ * Label i18n key for the rendered metadata
+ */
+ label : string;
+
+ /**
+ * Separator string between multiple values of the metadata fields defined
+ * @type {string}
+ */
+ separator : string = "
";
+
+ constructor() {
+ this.universalInit();
+ }
+
+ universalInit() {
+
+ }
+}
diff --git a/src/app/item-page/specific-field/title/item-page-title-field.component.html b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.html
similarity index 100%
rename from src/app/item-page/specific-field/title/item-page-title-field.component.html
rename to src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.html
diff --git a/src/app/item-page/specific-field/title/item-page-title-field.component.ts b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts
similarity index 77%
rename from src/app/item-page/specific-field/title/item-page-title-field.component.ts
rename to src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts
index 6dc2d159c8..4f926000a4 100644
--- a/src/app/item-page/specific-field/title/item-page-title-field.component.ts
+++ b/src/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit, Input } from '@angular/core';
-import { Item } from "../../../core/shared/item.model";
+import { Component, Input } from '@angular/core';
+import { Item } from "../../../../../core/shared/item.model";
import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component";
@Component({
diff --git a/src/app/item-page/specific-field/uri/item-page-uri-field.component.html b/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html
similarity index 100%
rename from src/app/item-page/specific-field/uri/item-page-uri-field.component.html
rename to src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html
diff --git a/src/app/item-page/specific-field/uri/item-page-uri-field.component.ts b/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts
similarity index 78%
rename from src/app/item-page/specific-field/uri/item-page-uri-field.component.ts
rename to src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts
index 4f7b0bb874..4879fa5aa6 100644
--- a/src/app/item-page/specific-field/uri/item-page-uri-field.component.ts
+++ b/src/app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.ts
@@ -1,5 +1,5 @@
-import { Component, OnInit, Input } from '@angular/core';
-import { Item } from "../../../core/shared/item.model";
+import { Component, Input } from '@angular/core';
+import { Item } from "../../../../../core/shared/item.model";
import { ItemPageSpecificFieldComponent } from "../item-page-specific-field.component";
@Component({
diff --git a/src/app/item-page/item-page.component.html b/src/app/item-page/simple/item-page.component.html
similarity index 82%
rename from src/app/item-page/item-page.component.html
rename to src/app/item-page/simple/item-page.component.html
index 47e5330ca5..9378c3839b 100644
--- a/src/app/item-page/item-page.component.html
+++ b/src/app/item-page/simple/item-page.component.html
@@ -8,12 +8,19 @@
+
+
diff --git a/src/app/item-page/metadata-uri-values/metadata-uri-values.component.scss b/src/app/item-page/simple/item-page.component.scss
similarity index 100%
rename from src/app/item-page/metadata-uri-values/metadata-uri-values.component.scss
rename to src/app/item-page/simple/item-page.component.scss
diff --git a/src/app/item-page/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts
similarity index 50%
rename from src/app/item-page/item-page.component.ts
rename to src/app/item-page/simple/item-page.component.ts
index c0dcafb3b0..53e57f3ae1 100644
--- a/src/app/item-page/item-page.component.ts
+++ b/src/app/item-page/simple/item-page.component.ts
@@ -1,10 +1,16 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
-import { Item } from "../core/shared/item.model";
-import { ItemDataService } from "../core/data/item-data.service";
-import { RemoteData } from "../core/data/remote-data";
+import { Item } from "../../core/shared/item.model";
+import { ItemDataService } from "../../core/data/item-data.service";
+import { RemoteData } from "../../core/data/remote-data";
import { Observable } from "rxjs";
-import { Bitstream } from "../core/shared/bitstream.model";
+import { Bitstream } from "../../core/shared/bitstream.model";
+
+/**
+ * This component renders a simple item page.
+ * The route parameter 'id' is used to request the item it represents.
+ * All fields of the item that should be displayed, are defined in its template.
+ */
@Component({
selector: 'ds-item-page',
@@ -31,11 +37,16 @@ export class ItemPageComponent implements OnInit {
ngOnInit(): void {
this.sub = this.route.params.subscribe(params => {
- this.id = +params['id'];
- this.item = this.items.findById(params['id']);
- this.thumbnail = this.item.payload.flatMap(i => i.getThumbnail());
+ this.initialize(params);
});
}
+ initialize(params) {
+ this.id = +params['id'];
+ this.item = this.items.findById(params['id']);
+ this.thumbnail = this.item.payload.flatMap(i => i.getThumbnail());
+ }
+
+
}
diff --git a/src/app/item-page/specific-field/item-page-specific-field.component.ts b/src/app/item-page/specific-field/item-page-specific-field.component.ts
deleted file mode 100644
index 4161505ccc..0000000000
--- a/src/app/item-page/specific-field/item-page-specific-field.component.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Component, OnInit, Input } from '@angular/core';
-import { Item } from "../../core/shared/item.model";
-
-@Component({
- templateUrl: './item-page-specific-field.component.html'
-})
-export class ItemPageSpecificFieldComponent {
-
- @Input() item: Item;
-
- fields : string[];
-
- label : string;
-
- separator : string = "
";
-
- constructor() {
- this.universalInit();
- }
-
- universalInit() {
-
- }
-}
diff --git a/src/app/shared/utils/file-size-pipe.ts b/src/app/shared/utils/file-size-pipe.ts
index fbd3ae081c..e00092271e 100644
--- a/src/app/shared/utils/file-size-pipe.ts
+++ b/src/app/shared/utils/file-size-pipe.ts
@@ -9,6 +9,7 @@ import { Pipe, PipeTransform } from '@angular/core';
* {{ 1024 | fileSize}}
* formats to: 1 KB
*/
+
@Pipe({name: 'dsFileSize'})
export class FileSizePipe implements PipeTransform {
diff --git a/src/app/shared/utils/safe-url-pipe.ts b/src/app/shared/utils/safe-url-pipe.ts
index e05e58764b..a32aa18ab8 100644
--- a/src/app/shared/utils/safe-url-pipe.ts
+++ b/src/app/shared/utils/safe-url-pipe.ts
@@ -1,6 +1,11 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
+/**
+ * This pipe explicitly escapes the sanitization of a URL,
+ * only use this when you are sure the URL is indeed safe
+ */
+
@Pipe({name: 'dsSafeUrl'})
export class SafeUrlPipe implements PipeTransform {
constructor(private domSanitizer: DomSanitizer) {}
diff --git a/src/app/thumbnail/thumbnail.component.spec.ts b/src/app/thumbnail/thumbnail.component.spec.ts
new file mode 100644
index 0000000000..eb126287ba
--- /dev/null
+++ b/src/app/thumbnail/thumbnail.component.spec.ts
@@ -0,0 +1,49 @@
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
+
+import { ThumbnailComponent } from "./thumbnail.component";
+import { Bitstream } from "../core/shared/bitstream.model";
+import { SafeUrlPipe } from "../shared/utils/safe-url-pipe";
+
+
+describe('ThumbnailComponent', () => {
+ let comp: ThumbnailComponent;
+ let fixture: ComponentFixture;
+ let de: DebugElement;
+ let el: HTMLElement;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ThumbnailComponent, SafeUrlPipe]
+ })
+ .compileComponents();
+
+ }));
+
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ThumbnailComponent);
+
+ comp = fixture.componentInstance; // BannerComponent test instance
+ de = fixture.debugElement.query(By.css('div.thumbnail'));
+ el = de.nativeElement;
+ });
+
+
+ it('should display image', () => {
+ comp.thumbnail = new Bitstream();
+ comp.thumbnail.retrieve = "test.url";
+ fixture.detectChanges();
+ let image : HTMLElement = de.query(By.css('img')).nativeElement;
+ expect(image.getAttribute("src")).toBe(comp.thumbnail.retrieve);
+ });
+
+ it('should display placeholder', () => {
+ fixture.detectChanges();
+ let image : HTMLElement = de.query(By.css('img')).nativeElement;
+ expect(image.getAttribute("src")).toBe(comp.holderSource);
+ });
+
+
+});
\ No newline at end of file
diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts
index e8e226c004..61b9e31fbe 100644
--- a/src/app/thumbnail/thumbnail.component.ts
+++ b/src/app/thumbnail/thumbnail.component.ts
@@ -1,6 +1,12 @@
import { Component, Input, OnInit } from '@angular/core';
import { Bitstream } from "../core/shared/bitstream.model";
+/**
+ * This component renders a given Bitstream as a thumbnail.
+ * One input parameter of type Bitstream is expected.
+ * If no Bitstream is provided, a holderjs image will be rendered instead.
+ */
+
@Component({
selector: 'ds-thumbnail',
styleUrls: ['./thumbnail.component.css'],
diff --git a/src/backend/bitstreams.ts b/src/backend/bitstreams.ts
index 537cd5890b..da6a87e042 100644
--- a/src/backend/bitstreams.ts
+++ b/src/backend/bitstreams.ts
@@ -43,6 +43,40 @@ export const BITSTREAMS = {
],
"format": "JPEG",
"mimetype": "image/jpeg"
- }
+ },
+ {
+ "_links": {
+ "self": { "href": "/bitstreams/8934" },
+ "bundle": { "href": "/bundles/99f78e5e-3677-43b0-aaef-cddaa1a49092" },
+ "retrieve": { "href": "/rest/bitstreams/ba7d24f2-8fc7-4b8e-b7b6-6c32be1c12a6/retrieve" }
+ },
+ "id": "8934",
+ "uuid": "ba7d24f2-8fc7-4b8e-b7b6-6c32be1c12a6",
+ "name": "license.txt",
+ "size": 41183,
+ "checksum": {
+ "value": "8ad416e8a39e645020e13e06f1427814",
+ "algorithm": "MD5"
+ },
+ "metadata": [
+ { "key": "dc.title", "value": "license.txt", "language": null },
+ { "key": "dc.description", "value": "License", "language": "en" }
+ ],
+ "format": "Text",
+ "mimetype": "text/plain"
+ },
+ {
+ "_links": {
+ "self": { "href": "/bitstreams/4688" },
+ },
+ "id": "4688",
+ "uuid": "1bb1be24-c934-41e3-a0fb-ca7a71ab0e71",
+ "type": "bitstream",
+ "name": "collection-5179-logo.png",
+ "size": 299832,
+ "url": "/bitstreams/1bb1be24-c934-41e3-a0fb-ca7a71ab0e71/retrieve",
+ "format": "PNG",
+ "mimetype": "image/png"
+ },
]
};
diff --git a/src/backend/bundles.ts b/src/backend/bundles.ts
index 5370c1a5a3..b7411c6412 100644
--- a/src/backend/bundles.ts
+++ b/src/backend/bundles.ts
@@ -37,6 +37,24 @@ export const BUNDLES = {
"metadata": [
{ "key": "dc.title", "value": "THUMBNAIL", "language": "en" }
]
+ },
+ {
+ "_links": {
+ "self": { "href": "/bundles/8475" },
+ "items": [
+ { "href": "/items/8871" }
+ ],
+ "bitstreams": [
+ { "href": "/bitstreams/8934" },
+ ],
+ "primaryBitstream": { "href": "/bitstreams/8934" }
+ },
+ "id": "8475",
+ "uuid": "99f78e5e-3677-43b0-aaef-cddaa1a49092",
+ "name": "LICENSE",
+ "metadata": [
+ { "key": "dc.title", "value": "LICENSE", "language": "en" }
+ ]
}
]
};
diff --git a/src/backend/collections.ts b/src/backend/collections.ts
index ffc56b0140..5170f14c46 100644
--- a/src/backend/collections.ts
+++ b/src/backend/collections.ts
@@ -6,7 +6,8 @@ export const COLLECTIONS = {
"items": [
{ "href": "/items/8871" },
{ "href": "/items/9978" }
- ]
+ ],
+ "logo": { "href": "/bitstreams/4688" }
},
"id": "5179",
"uuid": "9e32a2e2-6b91-4236-a361-995ccdc14c60",
diff --git a/src/backend/items.ts b/src/backend/items.ts
index eb69821037..63913f8245 100644
--- a/src/backend/items.ts
+++ b/src/backend/items.ts
@@ -17,9 +17,12 @@ export const ITEMS = {
{
"href": "/bundles/2355"
},
- // {
- // "href": "/bundles/5687"
- // }
+ {
+ "href": "/bundles/5687"
+ },
+ {
+ "href": "/bundles/8475"
+ }
]
},
"id": "8871",
@@ -91,86 +94,7 @@ 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": {
@@ -189,9 +113,9 @@ export const ITEMS = {
{
"href": "/bundles/2355"
},
- // {
- // "href": "/bundles/5687"
- // }
+ {
+ "href": "/bundles/5687"
+ }
]
},
"id": "9978",
@@ -243,39 +167,7 @@ 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",
- }
- ]
- }
+ ]
}
]
};
diff --git a/src/server.routes.ts b/src/server.routes.ts
index 704ea15df5..19ba0264aa 100644
--- a/src/server.routes.ts
+++ b/src/server.routes.ts
@@ -10,5 +10,5 @@
* ];
**/
export const routes: string[] = [
- 'home', 'items/:id' , '**'
+ 'home', 'items/:id' , 'collections/:id', '**'
];
diff --git a/src/server.ts b/src/server.ts
index 13837821d0..42f8d9bd5e 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -82,22 +82,25 @@ function ngApp(req, res) {
function onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
console.warn('Error in SSR, serving for direct CSR');
res.sendFile('index.html', { root: './src' });
- return false;
}
- Zone.current.fork({ name: 'CSR fallback', onHandleError }).run(() => {
- res.render('index', {
- req,
- res,
- // time: true, // use this to determine what part of your app is slow only in development
- async: EnvConfig.universal.async,
- preboot: EnvConfig.universal.preboot,
- baseUrl: EnvConfig.ui.nameSpace,
- requestUrl: req.originalUrl,
- originUrl: EnvConfig.ui.baseUrl
+ if (EnvConfig.universal.preboot) {
+ Zone.current.fork({ name: 'CSR fallback', onHandleError }).run(() => {
+ res.render('index', {
+ req,
+ res,
+ // time: true, // use this to determine what part of your app is slow only in development
+ async: EnvConfig.universal.async,
+ preboot: EnvConfig.universal.preboot,
+ baseUrl: EnvConfig.ui.nameSpace,
+ requestUrl: req.originalUrl,
+ originUrl: EnvConfig.ui.baseUrl
+ });
});
- });
-
+ }
+ else {
+ res.sendFile('index.html', { root: './src' });
+ }
}
/**
diff --git a/yarn.lock b/yarn.lock
index 17ed417d48..c1e67e8572 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -301,14 +301,10 @@ alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
-amdefine@1.0.0:
+amdefine@1.0.0, amdefine@>=0.0.4:
version "1.0.0"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.0.tgz#fd17474700cb5cc9c2b709f0be9d23ce3c198c33"
-amdefine@>=0.0.4:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
-
angular2-express-engine@2.1.0-rc.1:
version "2.1.0-rc.1"
resolved "https://registry.yarnpkg.com/angular2-express-engine/-/angular2-express-engine-2.1.0-rc.1.tgz#79c8e481cde7ff1253b373cbf98de7c9fab4f215"
@@ -3521,11 +3517,7 @@ lowercase-keys@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
-lru-cache@2:
- version "2.7.3"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
-
-lru-cache@2.2.x:
+lru-cache@2, lru-cache@2.2.x:
version "2.2.4"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
@@ -4659,14 +4651,10 @@ punycode@^1.2.4, punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
-q@1.4.1:
+q@1.4.1, q@^1.1.2, q@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
-q@^1.1.2, q@^1.4.1:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
-
qjobs@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73"
@@ -5063,13 +5051,13 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.6.0, rimraf@^2.6.1:
+rimraf@2, rimraf@^2.2.8, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.6.0, rimraf@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
dependencies:
glob "^7.0.5"
-rimraf@2.5.4, rimraf@^2.4.4:
+rimraf@2.5.4:
version "2.5.4"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04"
dependencies: